Next: , Previous: , Up: TC-7   [Contents][Index]

#### 4.16.2 TC-7 Samples

The goal of TC-7 is straightforward: starting from LIR, generate the MIPS instructions, except that you don’t have actual registers: we still heavily use `Temp`s. Register allocation will be done in a later stage, TC-9.

```let
in
end
```

```\$ tc --inst-display the-answer.tig
# == Final assembler ouput. == #
# Routine: _main
tc_main:
# Allocate frame
move    \$x11, \$ra
move    \$x3, \$s0
move    \$x4, \$s1
move    \$x5, \$s2
move    \$x6, \$s3
move    \$x7, \$s4
move    \$x8, \$s5
move    \$x9, \$s6
move    \$x10, \$s7
l0:
li      \$x1, 42
sw      \$x1, (\$fp)
li      \$x2, 51
sw      \$x2, (\$fp)
l1:
move    \$s0, \$x3
move    \$s1, \$x4
move    \$s2, \$x5
move    \$s3, \$x6
move    \$s4, \$x7
move    \$s5, \$x8
move    \$s6, \$x9
move    \$s7, \$x10
move    \$ra, \$x11
# Deallocate frame
jr      \$ra
```

At this stage the compiler cannot know what registers are used; that’s why in the previous output it saves "uselessly" all the callee-save registers on `main` entry. For the same reason, the frame is not allocated.

While Nolimips accepts the lack of register allocation, it does require the frame to be allocated. That is the purpose of --nolimips-display:

```\$ tc --nolimips-display the-answer.tig
# == Final assembler ouput. == #
# Routine: _main
tc_main:
sw      \$fp, -4 (\$sp)
move    \$fp, \$sp
sub     \$sp, \$sp, 8
move    \$x11, \$ra
move    \$x3, \$s0
move    \$x4, \$s1
move    \$x5, \$s2
move    \$x6, \$s3
move    \$x7, \$s4
move    \$x8, \$s5
move    \$x9, \$s6
move    \$x10, \$s7
l0:
li      \$x1, 42
sw      \$x1, (\$fp)
li      \$x2, 51
sw      \$x2, (\$fp)
l1:
move    \$s0, \$x3
move    \$s1, \$x4
move    \$s2, \$x5
move    \$s3, \$x6
move    \$s4, \$x7
move    \$s5, \$x8
move    \$s6, \$x9
move    \$s7, \$x10
move    \$ra, \$x11
move    \$sp, \$fp
lw      \$fp, -4 (\$fp)
jr      \$ra
```

The final stage, register allocation, addresses both issues. For your information, it results in:

```\$ tc -sI the-answer.tig
# == Final assembler ouput. == #
# Routine: _main
tc_main:
sw      \$fp, -4 (\$sp)
move    \$fp, \$sp
sub     \$sp, \$sp, 8
l0:
li      \$t0, 42
sw      \$t0, (\$fp)
li      \$t0, 51
sw      \$t0, (\$fp)
l1:
move    \$sp, \$fp
lw      \$fp, -4 (\$fp)
jr      \$ra
```

A delicate part of this exercise is handling the function calls:

```let function add(x: int, y: int) : int = x + y
in
end
```

```\$ tc -e --inst-display add.tig
# == Final assembler ouput. == #
tc_l0:
# Allocate frame
move    \$x15, \$ra
sw      \$a0, (\$fp)
move    \$x0, \$a1
move    \$x1, \$a2
move    \$x7, \$s0
move    \$x8, \$s1
move    \$x9, \$s2
move    \$x10, \$s3
move    \$x11, \$s4
move    \$x12, \$s5
move    \$x13, \$s6
move    \$x14, \$s7
l2:
move    \$v0, \$x6
l3:
move    \$s0, \$x7
move    \$s1, \$x8
move    \$s2, \$x9
move    \$s3, \$x10
move    \$s4, \$x11
move    \$s5, \$x12
move    \$s6, \$x13
move    \$s7, \$x14
move    \$ra, \$x15
# Deallocate frame
jr      \$ra

.data
l1:
.word 1
.asciiz "\n"
.text

# Routine: _main
tc_main:
# Allocate frame
move    \$x28, \$ra
move    \$x20, \$s0
move    \$x21, \$s1
move    \$x22, \$s2
move    \$x23, \$s3
move    \$x24, \$s4
move    \$x25, \$s5
move    \$x26, \$s6
move    \$x27, \$s7
l4:
move    \$a0, \$fp
li      \$x16, 2
move    \$a1, \$x16
li      \$x17, 3
move    \$a2, \$x17
jal     tc_l0
move    \$x4, \$v0
move    \$a0, \$fp
li      \$x18, 1
move    \$a1, \$x18
move    \$a2, \$x4
jal     tc_l0
move    \$x5, \$v0
move    \$a0, \$x5
jal     tc_print_int
la      \$x19, l1
move    \$a0, \$x19
jal     tc_print
l5:
move    \$s0, \$x20
move    \$s1, \$x21
move    \$s2, \$x22
move    \$s3, \$x23
move    \$s4, \$x24
move    \$s5, \$x25
move    \$s6, \$x26
move    \$s7, \$x27
move    \$ra, \$x28
# Deallocate frame
jr      \$ra
```

Example 4.113: tc -e --inst-display add.tig

Once your function calls work properly, you can start using Nolimips (using options --nop-after-branch --unlimited-registers --execute) to check the behavior of your compiler.

```\$ tc -eR --nolimips-display add.tig >add.nolimips
```

```\$ nolimips -l nolimips -Nue add.nolimips
6
```

Example 4.115: nolimips -l nolimips -Nue add.nolimips

You must also complete the runtime. No difference must be observable between a run with HAVM and another with Nolimips:

```substring("", 1, 1)
```

File 4.71: substring-0-1-1.tig

```\$ tc -e --nolimips-display substring-0-1-1.tig
# == Final assembler ouput. == #
.data
l0:
.word 0
.asciiz ""
.text

# Routine: _main
tc_main:
# Allocate frame
move    \$x12, \$ra
move    \$x4, \$s0
move    \$x5, \$s1
move    \$x6, \$s2
move    \$x7, \$s3
move    \$x8, \$s4
move    \$x9, \$s5
move    \$x10, \$s6
move    \$x11, \$s7
l1:
la      \$x1, l0
move    \$a0, \$x1
li      \$x2, 1
move    \$a1, \$x2
li      \$x3, 1
move    \$a2, \$x3
jal     tc_substring
l2:
move    \$s0, \$x4
move    \$s1, \$x5
move    \$s2, \$x6
move    \$s3, \$x7
move    \$s4, \$x8
move    \$s5, \$x9
move    \$s6, \$x10
move    \$s7, \$x11
move    \$ra, \$x12
# Deallocate frame
jr      \$ra
```

Example 4.116: tc -e --nolimips-display substring-0-1-1.tig

```\$ tc -eR --nolimips-display substring-0-1-1.tig >substring-0-1-1.nolimips
```

Example 4.117: tc -eR --nolimips-display substring-0-1-1.tig >substring-0-1-1.nolimips

```\$ nolimips -l nolimips -Nue substring-0-1-1.nolimips
error→substring: arguments out of bounds
⇒120
```

Example 4.118: nolimips -l nolimips -Nue substring-0-1-1.nolimips

Next: , Previous: , Up: TC-7   [Contents][Index]