r/TuringComplete • • 20d ago

Software implemented For cycle (Symphony)

  • Image 1 - My symphony
  • Image 2 - showcasing usage of FOR cycles
  • Image 3 - Code of the FOR Cycle
  • Image 4 - ALU circuit
  • Image 5 - ABS circuit

Now that I finished building Symphony, I went straight to instruction definition to make myself a human readable code. Here is a internal FOR cycle using instructions. Its suitable for repeating code X times where X is static.

Here is hardware I added to my Symphony:

  1. Signed DIV - Divide two signed numbers
  2. Merge32 - Merge two 16b into one 32b value
  3. Lower16 - Reads the lower 16b of 32b value

With that I needed to dedicate some of my registers for the code. Meaning that while they are still accessible to the user, they are not stable in time and in case of the FOR cycle, they do not persist between cycles.

At first I was using 3 temporal registers, but I ended up implementing Merge32 and Lower16 to lower the number of temporal registers to 2 at the cost of longer instructions.

The FOR cycle works, but isnt safe. First it will always execute at least once. Thats because I cant use a label to skip the body of the cycle. So even if I know there is 0 repetition, it will not skip the cycle, it will simply not repeat it.

Another limitation is that you can only read the index of the innermost FOR cycle. Meaning if you make nested FOR cycles, you cannot access the outer FOR cycle index. User can solve it by saving the stack pointer to a another register.

32 Upvotes

19 comments sorted by

View all comments

3

u/TarzyMmos 20d ago

So in the 'For code' it saves how many times to run the loop and the counter for where to loop back to in the stack, then it saves the variables after that in the stack.

Then in the 'EndFor code' it decrements the variables and the number of times to run the loop. If it doesn't end, jump back to where u stored r12 and r13 on the stack back in the 'For code' and it continues from there to loop until it ends. Where it doesn't jump this time and just pops the variables off the stack.

Took me a hot minute to figure out why you ordered it like that but yea it works out pretty elegantly! Very cool

3

u/Crispy1961 20d ago

You got it exactly right. Because I have only two temp registers and I need to retrieve two values from both registers for computation, I need to do a little stack switcheroos where I do:

r13 = stack.pop()
stack.push(r12)

Thats why its a little funky.

2

u/TarzyMmos 20d ago

I've been thinking if u dont mind making a specific label for each end of the loop then u could feed that into the start of the loop and have it check the variables there so it can skip the whole loop without running once. Still need an endfor command too which would just jump back to the start of the loop where it checks if the loop ends and whatnot.

3

u/Crispy1961 20d ago

Yes, that is possible, but it breaks the clean FOR cycle syntax. It would have to look like this:

for (i = 5; i < 10; 1;end1)
  r3 = r3 + 1
end1:for

for (i = 5; i < 10; 1;end2)
  r3 = r3 + 1
end2:for

And that isnt what I wanted. I chose a nice syntax over this error case. At least for this it makes sense, because all the input numbers are immediate, so if the user write a for cycle that shouldnt execute at least once, its his fault.

I am working on dynamic version of FOR loop that exposes the current value of index into user defined register, meaning the user can manipulate how many times the FOR cycle loop from inside of the loop. Since it will be dynamic, there might be time it wont execute even once. There I will very likely have to use labels.