Noeud « Next »: , Noeud « Previous »: T7 Goals, Noeud « Up »: T7



4.9.2 T7 Samples

The goal of T7 is straightforward: starting from LIR, generate the MIPS instructions, except that you don't have actual registers: we still heavily use Temps. Register allocation will be done in a later stage, T9.

     1 + 2 * 3
     File 118: seven.tig
     $ tc --inst-display seven.tig
     # == Final assembler ouput. == #
     # Routine: Main
     t_main:
             move    t5, $s0
             move    t6, $s1
             move    t7, $s2
             move    t8, $s3
             move    t9, $s4
             move    t10, $s5
             move    t11, $s6
             move    t12, $s7
     l0:
             li      t3, 2
             mul     t2, t3, 3
             li      t4, 1
             add     t1, t4, t2
     l1:
             move    $s0, t5
             move    $s1, t6
             move    $s2, t7
             move    $s3, t8
             move    $s4, t9
             move    $s5, t10
             move    $s6, t11
             move    $s7, t12

     Example 119: tc --inst-display seven.tig

Please, note that at this stage, the control flow analysis and the liveness analysis are not performed yet, therefore the compiler cannot know what registers are really to be saved. That's why in the previous output it saves "uselessly" all the callee-save registers on main entry. The next stage, which combines control flow analysis, liveness analysis, and register allocation, will make it useless. For your information, it results in:

     $ tc -sI seven.tig
     # == Final assembler ouput. == #
     # Routine: Main
     t_main:
             sw      $fp, ($sp)
             move    $fp, $sp
             sub     $sp, $sp, 8
             sw      $ra, -4 ($fp)
     l0:
             li      $t0, 2
             mul     $t1, $t0, 3
             li      $t0, 1
             add     $t0, $t0, $t1
     l1:

             lw      $ra, -4 ($fp)
             move    $sp, $fp
             lw      $fp, ($fp)
             jr      $ra
     Example 120: tc -sI seven.tig

A delicate part of this exercise is handling the function calls:
     let function add (x: int, y: int) : int = x + y
     in
       print_int (add (1, (add (2, 3)))); print ("\n")
     end
     File 121: add.tig
     $ tc -e --mipsy-display add.tig
     # == Final assembler ouput. == #
     # Routine: add
     l0:
             sw      $fp, -4 ($sp)
             move    $fp, $sp
             sub     $sp, $sp, 12
             sw      $ra, -8 ($fp)
             sw      $a0, ($fp)
             move    t0, $a1
             move    t1, $a2
             move    t7, $s0
             move    t8, $s1
             move    t9, $s2
             move    t10, $s3
             move    t11, $s4
             move    t12, $s5
             move    t13, $s6
             move    t14, $s7
     l2:
             add     t6, t0, t1
             move    $v0, t6
     l3:
             move    $s0, t7
             move    $s1, t8
             move    $s2, t9
             move    $s3, t10
             move    $s4, t11
             move    $s5, t12
             move    $s6, t13
             move    $s7, t14

             lw      $ra, -8 ($fp)
             move    $sp, $fp
             lw      $fp, -4 ($fp)
             jr      $ra

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

     # Routine: Main
     t_main:
             sw      $fp, ($sp)
             move    $fp, $sp
             sub     $sp, $sp, 8
             sw      $ra, -4 ($fp)
             move    t19, $s0
             move    t20, $s1
             move    t21, $s2
             move    t22, $s3
             move    t23, $s4
             move    t24, $s5
             move    t25, $s6
             move    t26, $s7
     l4:
             move    $a0, $fp
             li      t15, 2
             move    $a1, t15
             li      t16, 3
             move    $a2, t16
             jal     l0
             move    t4, $v0
             move    $a0, $fp
             li      t17, 1
             move    $a1, t17
             move    $a2, t4
             jal     l0
             move    t5, $v0
             move    $a0, t5
             jal     print_int
             la      t18, l1
             move    $a0, t18
             jal     print
     l5:
             move    $s0, t19
             move    $s1, t20
             move    $s2, t21
             move    $s3, t22
             move    $s4, t23
             move    $s5, t24
             move    $s6, t25
             move    $s7, t26

             lw      $ra, -4 ($fp)
             move    $sp, $fp
             lw      $fp, ($fp)
             jr      $ra
     Example 122: tc -e --mipsy-display add.tig

Once your function calls work properly, you can start using mipsy to check the behavior of your compiler.
     $ tc -eH add.tig >add.hir
     Example 123: tc -eH add.tig >add.hir
     $ havm add.hir
     6
     Example 124: havm add.hir

Unfortunately, you need to adjust the output of tc, using t123, to mipsy conventions: $x123.

     $ tc -eR --mipsy-display add.tig >add.instr
     Example 125: tc -eR --mipsy-display add.tig >add.instr
     $ sed -e's/\([^$a-z]\)t\([0-9][0-9]*\)/\1$x\2/g' add.instr >add.mipsy
     Example 126: sed -e's/\([^$a-z]\)t\([0-9][0-9]*\)/\1$x\2/g' add.instr >add.mipsy
     $ mipsy --unlimited-regs --execute add.mipsy
     6
     Example 127: mipsy --unlimited-regs --execute add.mipsy

You must also complete the runtime. No difference must be observable between a run with havm and another with mipsy:
     substring ("", 1, 1)
     File 128: substring-0-1-1.tig
     $ tc -eH substring-0-1-1.tig >substring-0-1-1.hir
     Example 129: tc -eH substring-0-1-1.tig >substring-0-1-1.hir
     $ havm substring-0-1-1.hir
     substring: arguments out of bounds
     =>120
     Example 130: havm substring-0-1-1.hir
     $ tc -e --mipsy-display substring-0-1-1.tig
     # == Final assembler ouput. == #
     .data
     l0:
             .word 0
             .asciiz ""
     .text

     # Routine: Main
     t_main:
             sw      $fp, ($sp)
             move    $fp, $sp
             sub     $sp, $sp, 8
             sw      $ra, -4 ($fp)
             move    t4, $s0
             move    t5, $s1
             move    t6, $s2
             move    t7, $s3
             move    t8, $s4
             move    t9, $s5
             move    t10, $s6
             move    t11, $s7
     l1:
             la      t1, l0
             move    $a0, t1
             li      t2, 1
             move    $a1, t2
             li      t3, 1
             move    $a2, t3
             jal     substring
     l2:
             move    $s0, t4
             move    $s1, t5
             move    $s2, t6
             move    $s3, t7
             move    $s4, t8
             move    $s5, t9
             move    $s6, t10
             move    $s7, t11

             lw      $ra, -4 ($fp)
             move    $sp, $fp
             lw      $fp, ($fp)
             jr      $ra
     Example 131: tc -e --mipsy-display substring-0-1-1.tig
     $ tc -eR --mipsy-display substring-0-1-1.tig >substring-0-1-1.instr
     Example 132: tc -eR --mipsy-display substring-0-1-1.tig >substring-0-1-1.instr
     $ sed -e's/\([^$a-z]\)t\([0-9][0-9]*\)/\1$x\2/g' substring-0-1-1.instr >substring-0-1-1.mipsy
     Example 133: sed -e's/\([^$a-z]\)t\([0-9][0-9]*\)/\1$x\2/g' substring-0-1-1.instr >substring-0-1-1.mipsy
     $ mipsy --unlimited-regs --execute substring-0-1-1.mipsy
     substring: arguments out of bounds
     =>120
     Example 134: mipsy --unlimited-regs --execute substring-0-1-1.mipsy