### translator.asm ## 378->SPIM-ifier ## hw3 CSE 378 ### notes: ## $s7 - filehandle ## $t9, s4 - loop counter .data inputFile: .asciiz "378.binary" outputFile: .asciiz "spim.asm" deadStr: .asciiz "der wer an error\n" magic378: .ascii "378 " line: .ascii "line" globlmain: .ascii "\n\n\t.text\n\t.globl main\nmain:\n\tmove\t$t9, $sp\n" .ascii "\tli\t$t8, 0\n\n" dotdata: .ascii "\t.data\nretstr:\t.asciiz\t\"\nProgram exited with code" .ascii " \"\ndatastart: " dotword: .ascii "\n\t.word\t" dotdatajt: .ascii "\n\njt:\t" addcode: .ascii "\taddi\t$t0, $sp, 8\n\tbgt\t$t0, $t9, error\n\tlw\t$t0," .ascii " 0($sp)\n\tlw\t$t1, 4($sp)\n\taddi\t$sp, $sp, 4\n\tadd" .ascii "\t$t0, $t0, $t1\n\tsw\t$t0, 0($sp)\n" subcode: .ascii "\taddi\t$t0, $sp, 8\n\tbgt\t$t0, $t9, error\n\tlw\t$t0," .ascii " 0($sp)\n\tlw\t$t1, 4($sp)\n\taddi\t$sp, $sp, 4\n\tsub" .ascii "\t$t0, $t1, $t0\n\tsw\t$t0, 0($sp)\n" multcode: .ascii "\taddi\t$t0, $sp, 8\n\tbgt\t$t0, $t9, error\n\tlw\t$t0," .ascii " 0($sp)\n\tlw\t$t1, 4($sp)\n\taddi\t$sp, $sp, 4\n\tmul" .ascii "\t$t0, $t1, $t0\n\tsw\t$t0, 0($sp)\n" bgtzcode: .ascii "\taddi\t$t0, $sp, 4\n\tbgt\t$t0, $t9, error\n\tlw\t$t0," .ascii " 0($sp)\n\taddi\t$sp, $sp, 4\n\tbgtz\t$t0, " bezcode: .ascii "\taddi\t$t0, $sp, 4\n\tbgt\t$t0, $t9, error\n\tlw\t$t0," .ascii " 0($sp)\n\taddi\t$sp, $sp, 4\n\tbeqz\t$t0, " jumpcode: .ascii "\taddi\t$t0, $sp, 4\n\tbgt\t$t0, $t9, error\n\tlw\t$t0," .ascii " 0($sp)\n\taddi\t$sp, $sp, 4\n\tlw\t$t1, jt($t0)\n\tjr" .ascii "\t$t1\n" loadcode: .ascii "\taddi\t$t0, $sp, 4\n\tbgt\t$t0, $t9, error\n\tlw\t$t0," .ascii " 0($sp)\n\tlw\t$t1, datastart($t0)\n\tsw\t$t1, 0($sp)\n" storcode: .ascii "\taddi\t$t0, $sp, 8\n\tbgt\t$t0, $t9, error\n\tlw\t$t0," .ascii " 0($sp)\n\tlw\t$t1, 4($sp)\n\tsw\t$t1, datastart($t0)\n" .ascii "\taddi\t$sp, $sp, 8\n" intcode0: .ascii "\tj\tend\n" intcode1: .ascii "\taddi\t$t0, $sp, 4\n\tbgt\t$t0, $t9, error\n\tlw\t$a0," .ascii " 0($sp)\n\tli\t$v0, 1\n\tsyscall\n\taddi\t$sp, $sp, 4\n" intcode2: .ascii "\taddi\t$sp, $sp, -4\n\tli\t$v0, 5\n\tsyscall\n\tsw" .ascii "\t$v0, 0($sp)\n" clercode: .ascii "\tmove\t$sp, $t9\n" pushcode1: .ascii "\taddi\t$sp, $sp, -4\n\tli\t$t0, -" pushcode2: .ascii "\n\tsw\t$t0, 0($sp)\n" endcode: .ascii "\nend:\tmove\t$sp, $t9\n\tla\t$a0, retstr\n\tli\t$v0, " .ascii "4\n\tsyscall\n\tmove\t$a0, $t8\n\tli\t$v0, 1\n\tsyscal" .ascii "l\n\tjr\t$ra\nerror:\tli\t$t8, 1\n\tj\tend\n" .align 2 jt: .word die # op code 0x0 not implemented .word opadd .word opsub .word opmult .word die # op code 0x4 not implemented .word opbgtz .word opbez .word opjump .word opload .word opstor .word opint .word die # op code 0xB not implemented .word die # op code 0xC not implemented .word opcler .word oppush intjt: .word opint0 opint1 opint2 .text .globl main main: addi $sp, $sp, -20 # space for $ra + 16 bytes of inputFile header sw $ra, 16($sp) # save return address ### Open the binary 378 file, read in the header. ### Read rest of file into memory, then open the output file ### ## open inputFile for read in binary mode la $a0, inputFile # file name string li $a1, 0x8000 # _O_BINARY file mode li $a2, 0 # no perms needed li $v0, 11 # open syscall syscall # bltz $v0, die # exit if error move $s7, $v0 # remember input file handle ## read in the first 16 bytes move $a0, $s7 # move in file descriptor add $a1, $sp, $0 # data goes into stack li $a2, 0x10 # get 16 bytes li $v0, 12 # read syscall syscall # ## is this a 378 binary? lw $t0, 0($sp) # first byte of file ulw $t1, magic378($0) # technically a string, so maybe unaligned bne $t0, $t1, die # test is NOT actually endian-dependant ## it is, so "parse" the header lw $s0, 4($sp) # datasize lw $s1, 8($sp) # codesize lw $s2, 12($sp) # IPC ## ask the OS for some memory and put the file there addu $a0, $s0, $s1 # need s0+s1 bytes of memory li $v0, 9 # sbrk syscall syscall # move $a0, $s7 # move in file descriptor move $a1, $v0 # memory space from sbrk addu $a2, $s0, $s1 # read s0+s1 bytes li $v0, 12 # read syscall syscall # move $s5, $a1 # s5 is start of data add $s6, $s5, $s0 # s6 is start of code move $a0, $s7 # don't need the input file anymore li $v0, 14 # close syscall (need to free up the fd) syscall # ## get us an output file la $a0, outputFile # file name string li $a1, 0x4302 # _O_TEXT | _O_TRUNC | _O_CREAT | _O_RDWR li $a2,0x180 # _S_IREAD | _S_IWRITE li $v0, 11 # open syscall syscall # bltz $v0, die # exit if error move $s7, $v0 # remember output file handle ### Print .data section ### Includes data from the 378 binary and the jump table ### ## print the data section to the output file move $a0, $s7 # output file descriptor la $a1, dotdata # string to write li $a2, 63 # 63 bytes of string li $v0, 13 # write syscall syscall # add $s4, $0, $0 # $s4 is loop counter ## print .data wloop: la $a1, dotword # string to write li $a2, 8 # 8 bytes worth of string li $v0, 13 # write syscall syscall # ## load the data word, convert to hex string add $t3, $s5, $s4 # address of the current data word lw $a0, 0($t3) # the current data word addi $a1, $sp, 0 # address to store hex string jal hexconv # ## print hex string to file move $a0, $s7 # output file descriptor move $a1, $sp # start writing at stack pointer li $a2, 10 # '0x' + 8 digit hex number li $v0, 13 # write syscall syscall # write syscall addi $s4, $s4, 4 # increment by word size blt $s4, $s0, wloop # loop while in data section ## print jumptable la $a1, dotdatajt # '\n\njt:\t' li $a2, 6 # 6 bytes li $v0, 13 # write syscall syscall # li $s4, 0 # instruction counter ulw $t0, line($0) # load string 'line' into $t0 sw $t0, 0($sp) # put at bottom of stack ## print '.word ' to file jtloop: la $a1, dotword # string to write li $a2, 8 # 8 bytes of string li $v0, 13 # write syscall syscall # ## print a label move $a0, $s4 # going to convert this to a hex string addi $a1, $sp, 4 # start hex string after 'line' jal hexconv # ## print 'line0x
' to file move $a0, $s7 # output file descriptor move $a1, $sp # start at bottom of stack li $a2, 14 # 'line' + '0x' + 8 hex digits li $v0, 13 # write syscall syscall # addi $s4, $s4, 4 # increment loop counter blt $s4, $s1, jtloop # loop to end of code ($s1 is codesize) ### Write body of output file. Jump to the appropriate op