This page covers an if/else if/else conditional statement in RISC-V.
This control-flow construct is used to select one among multiple mutually exclusive (only one is executed) conditions:
if (condition1) { ..do something.. } else if (condition2) { ..do a different thing.. } else { ..do something else.. } ..do things afterwards..
|
The flow execution, also called the Control-Flow Graph, for this portion of program is shown on the right.
The idea to create an implementation is that the assembly code gathers all
conditions in one place (the top of the conditional block) and then branches
to a block of code within the body of that conditional. Rather than skipping
code given a case (as was done before) the code branches when it hits that case.
This assembly code can have any number of conditionals and thus can be used for
long if/elif/.../else blocks. This style of assembly code can also be used to
implement a C/C++
switch-case
construct.
Consider this example:
if (count == 1) { ..do something.. }
else if (count <= 10) { ..do a different something.. }
else { ..do something else.. }
..do things afterwards..
Then, to run through the cases we have:
# Before conditional
# Case 1
li t1, 1 # t1 <- 1
beq t0, t1, _f3Body1 # if count == 1 goto _f3Body1
# Case 2
li t1, 10 # t1 <- 10
ble t0, t1, _f3Body2 # if count <= 10 goto _f3Body2
# Case 3
j _f3Else
_f3Body1:
# .. do something..
j _f3join
_f3Body3:
# .. do a different something..
j _f3join
_f3Else:
# .. do something else..
_f3join:
# ..do things afterwards..
At the end of the code that starts with the label _f3Else
there is no need for
the jump j _f3join
instruction because the flow of execution falls through to
that code. This is often the case when going from the last of several alternative
paths to the join point where all the paths join the execution.