import java.util.*; class FirstPass { public static Vector processLine(String inst) { // add commas to the standard StringTokenizer StringTokenizer st = new StringTokenizer(inst, " ,\n\r\f\t"); // make sure line isn't blank String instruction = "blah"; if(st.hasMoreTokens()) instruction = st.nextToken(); Vector stuff = new Vector(); /* Pseudo Instructions */ if(instruction.equals("abs")) { /*Absolute abs rdest, rsrc ## addu rdest, $0, rsrc slt $1, rsrc, $0 beq $1, $0, 8 sub rdest, $0, rsrc */ String rdest = st.nextToken(); String rsrc = st.nextToken(); stuff.add(".set noat"); stuff.add("addu " + rdest + ", $0, " + rsrc); stuff.add("slt $1, " + rsrc + ", $0"); stuff.add("beq $1, $0, 8"); stuff.add("sub " + rdest + ", $0, " + rsrc); stuff.add(".set at"); } else if(instruction.equals("div")) { String rdest = st.nextToken(); String src1 = st.nextToken(); if(!st.hasMoreTokens()) // two argument version { stuff.add(inst); } else // three argument pseudo instruction { /*Divide w/ overflow div rdest, rsrc1, src2 ## bne src2, $0, 8 break 7 div rsrc1, src2 mflo rdest */ String src2 = st.nextToken(); stuff.add("div " + src1 + ", " + src2); stuff.add("mflo " + rdest); } } else if(instruction.equals("divu")) { String rdest = st.nextToken(); String src1 = st.nextToken(); if(!st.hasMoreTokens()) // two argument version { stuff.add(inst); } else // three argument pseudo instruction { /*Divide w/o overflow divu rdest, rsrc1, src2 ## bne src2, $0, 8 break 7 divu rsrc1, src2 mflo rdest */ String src2 = st.nextToken(); stuff.add("divu " + src1 + ", " + src2); stuff.add("mflo " + rdest); } } else if(instruction.equals("mul")) { /*Multiply (No Overflow) mul rdest, rsrc1, src2 ## mult rsrc1, rsrc2 mflo rdest */ String rdest = st.nextToken(); String rsrc1 = st.nextToken(); String src2 = st.nextToken(); stuff.add("mult " + rsrc1 + ", " + src2); stuff.add("mflo " + rdest); } else if(instruction.equals("mulo")) { /* Multiply (With Overflow) mulo, rdest, rsrc1, rsc2 ## mult src1, src2 mfhi $1 mflo rdest sra rdest, rdest, 31 beq $1, src1, 8 break 7 mflo rdest */ String rdest = st.nextToken(); String rsrc1 = st.nextToken(); String rsrc2 = st.nextToken(); stuff.add("mult " + rsrc1 + ", " + rsrc2); stuff.add("mflo " + rdest); stuff.add("sra " + rdest + ", " + rdest + ", 31"); stuff.add("mflo " + rdest); } else if(instruction.equals("mulou")) { /* Unsigned multiply w/ overflow mulou rdest, rsrc1, src2 ## multu rsrc1, src2 mfhi $1 beq $1, $0, 8 break 7 mflo rdest */ String rdest = st.nextToken(); String rsrc1 = st.nextToken(); String src2 = st.nextToken(); stuff.add("multu " + rsrc1 + ", " + src2); stuff.add("mflo " + rdest); } else if(instruction.equals("neg")) { /* Negate value w/ overflow neg rdest, rsrc ## sub rdest, $0, rsrc */ String rdest = st.nextToken(); String rsrc = st.nextToken(); stuff.add("sub " + rdest + ", $0, " + rsrc); } else if(instruction.equals("negu")) { /* Negate value w/o overflow negu rdest, rsrc ## subu rdest, $0, rsrc */ String rdest = st.nextToken(); String rsrc = st.nextToken(); stuff.add("subu " + rdest + ", $0, " + rsrc); } else if(instruction.equals("not")) { /* Not not rdest, rsrc ## nor rdest, rsrc, $0 */ String rdest = st.nextToken(); String rsrc = st.nextToken(); stuff.add("nor " + rdest + ", " + rsrc + ", $0"); } else if(instruction.equals("rem")) { /* Remainder rem rdest, rsrc1, rsrc2 ## bne rsrc2, $0, 8 break 7 div rsrc1, rsrc2 mfhi rdest */ String rdest = st.nextToken(); String rsrc1 = st.nextToken(); String rsrc2 = st.nextToken(); stuff.add("bne " + rsrc2 + ", $0, 8"); stuff.add("break 7"); stuff.add("div " + rsrc1 + ", " + rsrc2); stuff.add("mfhi " + rdest); } else if(instruction.equals("remu")) { /* Unsigned Remainder remu rdest, rsrc1, rsrc2 ## bne rsrc2, $0, 8 break 7 divu rsrc1, rsrc2 mfhi rdest */ String rdest = st.nextToken(); String rsrc1 = st.nextToken(); String rsrc2 = st.nextToken(); stuff.add("bne " + rsrc2 + ", $0, 8"); stuff.add("break 7"); stuff.add("divu " + rsrc1 + ", " + rsrc2); stuff.add("mfhi " + rdest); } else if(instruction.equals("rol")) { /* Rotate left rol rdest, rsrc1, rsrc2 ## subu $1, $0, rsrc2 srlv $1, rsrc1, $1 sllv rdest, rsrc1, rsrc2 or rdest, rdest, $1 */ String rdest = st.nextToken(); String rsrc1 = st.nextToken(); String rsrc2 = st.nextToken(); stuff.add(".set noat"); stuff.add("subu $1, $0, " + rsrc2); stuff.add("srlv $1, " + rsrc1 + ", $1"); stuff.add("sllv " + rdest + ", " + rsrc1 + ", " + rsrc2); stuff.add("or " + rdest + ", " + rdest + ", $1"); stuff.add(".set at"); } else if(instruction.equals("ror")) { /* Rotate right ror rdest, rsrc1, rsrc2 ## subu $1, $0, rsrc2 sllv $1, rsrc1, $1 srlv rdest, rsrc1, rsrc2 or rdest, rdest, $1 */ String rdest = st.nextToken(); String rsrc1 = st.nextToken(); String rsrc2 = st.nextToken(); stuff.add(".set noat"); stuff.add("subu $1, $0, " + rsrc2); stuff.add("sllv $1, " + rsrc1 + ", $1"); stuff.add("srlv " + rdest + ", " + rsrc1 + ", " + rsrc2); stuff.add("or " + rdest + ", " + rdest + ", $1"); stuff.add(".set at"); } else if(instruction.equals("li")) { /* Load Immediate li rdest, imm ## ori rdest, $0, imm */ String rdest = st.nextToken(); String imm = st.nextToken(); // test if imm is a number or not int intimm = -128; try { intimm = Integer.parseInt(imm); } catch (NumberFormatException e) { } if(intimm == -128) // imm isn't a number so pass imm through without checking if it is < 16 bits { stuff.add("ori " + rdest + ", $0, " + imm); } else // fix immediates greater than 16 bits { int upper = intimm >>> 16; int lower = intimm & 0x0000FFFF; stuff.add("lui " + rdest + ", " + upper); stuff.add("ori " + rdest + ", " + rdest + ", " + lower); } } else if(instruction.equals("seq")) { /* Set equal seq rdest, rsrc1, rsrc2 ## beq rsrc2, rsrc1, 12 ori rdest, $0, 8 beq $0, $0, 8 ori rdest, $0, 1 */ String rdest = st.nextToken(); String rsrc1 = st.nextToken(); String rsrc2 = st.nextToken(); stuff.add("beq " + rsrc2 + ", " + rsrc1 + ", 12"); stuff.add("ori " + rdest + ", $0, 8"); stuff.add("beq $0, $0, 8"); stuff.add("ori " + rdest + ", $0, 1"); } else if(instruction.equals("sge")) { /* Set greater than equal sge rdest, rsrc1, rsrc2 ## bne rsrc2, rsrc1, 12 ori rdest, $0, 1 beq $0, $0, 8 slt rdest, rsrc2, rsrc1 */ String rdest = st.nextToken(); String rsrc1 = st.nextToken(); String rsrc2 = st.nextToken(); stuff.add("bne " + rsrc2 + ", " + rsrc1 + ", 12"); stuff.add("ori " + rdest + ", $0, 1"); stuff.add("beq $0, $0, 8"); stuff.add("slt " + rdest + ", " + rsrc2 + ", " + rsrc1); } else if(instruction.equals("sgeu")) { /* Set greater than equal unsigned sgeu rdest, rsrc1, rsrc2 ## bne rsrc2, rsrc1, 12 ori rdest, $0, 1 beq $0, $0, 8 sltu rdest, rsrc2, rsrc1 */ String rdest = st.nextToken(); String rsrc1 = st.nextToken(); String rsrc2 = st.nextToken(); stuff.add("bne " + rsrc2 + ", " + rsrc1 + ", 12"); stuff.add("ori " + rdest + ", $0, 1"); stuff.add("beq $0, $0, 8"); stuff.add("sltu " + rdest + ", " + rsrc2 + ", " + rsrc1); } else if(instruction.equals("sgt")) { /* Set greater than sgt rdest, rsrc1, rsrc2 ## slt rdest, rsrc2, rsrc1 */ String rdest = st.nextToken(); String rsrc1 = st.nextToken(); String rsrc2 = st.nextToken(); stuff.add("slt " + rdest + ", " + rsrc2 + ", " + rsrc1); } else if(instruction.equals("sgtu")) { /* Set greater than unsigned sgtu rdest, rsrc1, rsrc2 ## sltu rdest, rsrc2, rsrc1 */ String rdest = st.nextToken(); String rsrc1 = st.nextToken(); String rsrc2 = st.nextToken(); stuff.add("sltu " + rdest + ", " + rsrc2 + ", " + rsrc1); } else if(instruction.equals("sle")) { /* Set less than equal sle rdest, rsrc1, rsrc2 ## bne rsrc2, rsrc1, 12 ori rdest, $0, 1 beq $0, $0, 8 slt rdest, rsrc1, rsrc2 */ String rdest = st.nextToken(); String rsrc1 = st.nextToken(); String rsrc2 = st.nextToken(); stuff.add("bne " + rsrc2 + ", " + rsrc1 + ", 12"); stuff.add("ori " + rdest + ", $0, 1"); stuff.add("beq $0, $0, 8"); stuff.add("slt " + rdest + ", " + rsrc1 + ", " + rsrc2); } else if(instruction.equals("sleu")) { /* Set less than equal sleu rdest, rsrc1, rsrc2 ## bne rsrc2, rsrc1, 12 ori rdest, $0, 1 beq $0, $0, 8 sltu rdest, rsrc1, rsrc2 */ String rdest = st.nextToken(); String rsrc1 = st.nextToken(); String rsrc2 = st.nextToken(); stuff.add("bne " + rsrc2 + ", " + rsrc1 + ", 12"); stuff.add("ori " + rdest + ", $0, 1"); stuff.add("beq $0, $0, 8"); stuff.add("sltu " + rdest + ", " + rsrc1 + ", " + rsrc2); } else if(instruction.equals("sne")) { /* Set not equal sne rdest, rsrc1, rsrc2 ## beq rsrc2, rsrc1, 12 ori rdest, $0, 1 beq $0, $0, 8 ori rdest, $0, 0 */ String rdest = st.nextToken(); String rsrc1 = st.nextToken(); String rsrc2 = st.nextToken(); stuff.add("beq " + rsrc2 + ", " + rsrc1 + ", 12"); stuff.add("ori " + rdest + ", $0, 1"); stuff.add("beq $0, $0, 8"); stuff.add("ori " + rdest + ", $0, 0"); } else if(instruction.equals("b")) { /* Branch b label ## beq $0, $0, label */ String label = st.nextToken(); stuff.add("beq $0, $0, " + label); } else if(instruction.equals("beqz")) { /* Branch on equal zero beqz rsrc, label ## beq rsrc, $0, label */ String rsrc = st.nextToken(); String label = st.nextToken(); stuff.add("beq " + rsrc + ", " + label); } else if(instruction.equals("bge")) { /* Branch on greater than equal bge rsrc1, rsrc2, label ## slt $1, rsrc1, rsrc2 beq $1, $0, label */ String rsrc1 = st.nextToken(); String rsrc2 = st.nextToken(); String label = st.nextToken(); stuff.add(".set noat"); stuff.add("slt $1, " + rsrc1 + ", " + rsrc2); stuff.add("beq $1, $0, " + label); stuff.add(".set at"); } else if(instruction.equals("bgeu")) { /* Branch on greater than equal unsigned bgeu rsrc1, rsrc2, label ## sltu $1, rsrc1, rsrc2 beq $1, $0, label */ String rsrc1 = st.nextToken(); String rsrc2 = st.nextToken(); String label = st.nextToken(); stuff.add(".set noat"); stuff.add("sltu $1, " + rsrc1 + ", " + rsrc2); stuff.add("beq $1, $0, " + label); stuff.add(".set at"); } else if(instruction.equals("bgt")) { /* Branch on greater than bgt rsrc1, rsrc2, label ## slt $1, rsrc2, rsrc1 bne $1, $0, label */ String rsrc1 = st.nextToken(); String rsrc2 = st.nextToken(); String label = st.nextToken(); stuff.add(".set noat"); stuff.add("slt $1, " + rsrc2 + ", " + rsrc1); stuff.add("bne $1, $0, " + label); stuff.add(".set at"); } else if(instruction.equals("bgtu")) { /* Branch on greater than unsigned bgtu rsrc1, rsrc2, label ## sltu $1, rsrc2, rsrc1 bne $1, $0, label */ String rsrc1 = st.nextToken(); String rsrc2 = st.nextToken(); String label = st.nextToken(); stuff.add(".set noat"); stuff.add("sltu $1, " + rsrc2 + ", " + rsrc1); stuff.add("bne $1, $0, " + label); stuff.add(".set at"); } else if(instruction.equals("ble")) { /* Branch on less than equal ble rsrc1, rsrc2, label ## slt $1, rsrc2, rsrc1 beq $1, $0, label */ String rsrc1 = st.nextToken(); String rsrc2 = st.nextToken(); String label = st.nextToken(); stuff.add(".set noat"); stuff.add("slt $1, " + rsrc2 + ", " + rsrc1); stuff.add("beq $1, $0, " + label); stuff.add(".set at"); } else if(instruction.equals("bleu")) { /* Branch on less than equal unsigned bleu rsrc1, rsrc2, label ## sltu $1, rsrc2, rsrc1 beq $1, $0, label */ String rsrc1 = st.nextToken(); String rsrc2 = st.nextToken(); String label = st.nextToken(); stuff.add(".set noat"); stuff.add("sltu $1, " + rsrc2 + ", " + rsrc1); stuff.add("beq $1, $0, " + label); stuff.add(".set at"); } else if(instruction.equals("blt")) { /* Branch on less than ble rsrc1, rsrc2, label ## slt $1, rsrc1, rsrc2 bne $1, $0, label */ String rsrc1 = st.nextToken(); String rsrc2 = st.nextToken(); String label = st.nextToken(); stuff.add(".set noat"); stuff.add("slt $1, " + rsrc1 + ", " + rsrc2); stuff.add("bne $1, $0, " + label); stuff.add(".set at"); } else if(instruction.equals("bltu")) { /* Branch on less than unsigned bleu rsrc1, src2, label ## sltu $1, rsrc1, src2 bne $1, $0, label */ String rsrc1 = st.nextToken(); String rsrc2 = st.nextToken(); String label = st.nextToken(); stuff.add(".set noat"); stuff.add("sltu $1, " + rsrc1 + ", " + rsrc2); stuff.add("bne $1, $0, " + label); stuff.add(".set at"); } else if(instruction.equals("bnez")) { /* Branch on not equal zero bnez rsrc, label ## bne rsrc, $0, label */ String rsrc = st.nextToken(); String label = st.nextToken(); stuff.add("bne " + rsrc + ", $0, " + label); } else if(instruction.equals("la")) { /* Load Address la rdest, address ## ori rdest, $0, address */ String rdest = st.nextToken(); String address = st.nextToken(); // test if address is a number or not int intadd = -128; try { intadd = Integer.parseInt(address); } catch (NumberFormatException e) { } if(intadd == -128) // if it isn't a number... { StringTokenizer addreg = new StringTokenizer(address, " ()\t\n"); String tok = addreg.nextToken(); if(addreg.hasMoreTokens()) // instuction in form la $1, 1234($2) { intadd = Integer.parseInt(tok); String rs = addreg.nextToken(); // fix immediates greater than 16 bits int upper = intadd >>> 16; int lower = intadd & 0x0000FFFF; stuff.add(".set noat"); stuff.add("lui $1, " + upper); stuff.add("ori $1, $1, " + lower); stuff.add("add " + rdest + ", $1, " + rs); stuff.add(".set at"); } else // instruction in form la $1, textlabel { stuff.add(inst); } } else // instuction in form la $1, 1234 { int upper = intadd >>> 16; int lower = intadd & 0x0000FFFF; stuff.add("lui " + rdest + ", " + upper); stuff.add("ori " + rdest + ", " + rdest + ", " + lower); } } else if(instruction.equals("ulh")) { /* Unaligned load halfword ulh rdest, address ## lb rdest, address+1($0) lbu $1, 1234($0) sll rdest, rdest, 8 or rdest, rdest, $1 */ String rdest = st.nextToken(); String address = st.nextToken(); stuff.add(".set noat"); stuff.add("lb " + rdest + ", " + address + "+1($0)"); stuff.add("lbu $1, " + address + "($0)"); stuff.add("sll " + rdest + ", " + rdest + ", 8"); stuff.add("or " + rdest + ", " + rdest + ", $1"); stuff.add(".set at"); } else if(instruction.equals("ulhu")) { /* Unaligned load halfword unsigned ulhu rdest, address ## lbu rdest, address+1($0) lbu $1, 1234($0) sll rdest, rdest, 8 or rdest, rdest, $1 */ String rdest = st.nextToken(); String address = st.nextToken(); stuff.add(".set noat"); stuff.add("lbu " + rdest + ", " + address + "+1($0)"); stuff.add("lbu $1, " + address + "($0)"); stuff.add("sll " + rdest + ", " + rdest + ", 8"); stuff.add("or " + rdest + ", " + rdest + ", $1"); stuff.add(".set at"); } else if(instruction.equals("ulw")) { /* Unalligned load word ulw rdest, address ## lwl rdest, address+3($0) lwr rdest, address($0) */ String rdest = st.nextToken(); String address = st.nextToken(); stuff.add("lwl " + rdest + ", " + address + "+3($0)"); stuff.add("lwr " + rdest + ", " + address + "($0)"); } else if(instruction.equals("sd")) { /* Store doubleword sd rsrc, address ## sw rsrc, address($0) sw rsrc+1, address+4($0) */ String rsrc = st.nextToken(); String address = st.nextToken(); stuff.add("sw " + rsrc + ", " + address + "($0)"); stuff.add("sw " + rsrc + ", " + address + "+4($0)"); } else if(instruction.equals("ush")) { /* Unaligned store halfword ush rsrc, address ## sb rsrc, address($0) srl $1, rsrc, 8 sb $1, address+1($0) */ String rsrc = st.nextToken(); String address = st.nextToken(); stuff.add(".set noat"); stuff.add("sb " + rsrc + ", " + address + "($0)"); stuff.add("srl $1, " + rsrc + ", 8"); stuff.add("sb $1, " + address + "+1($0)"); stuff.add(".set at"); } else if(instruction.equals("usw")) { /* Unaligned store word usw rsrc, address ## swl rsrc, address+3($0) swr rsrc, address($0) */ String rsrc = st.nextToken(); String address = st.nextToken(); stuff.add("swl " + rsrc + ", " + address + "+3($0)"); stuff.add("swr " + rsrc + ", " + address + "($0)"); } else if(instruction.equals("move")) { /* Move move rdest, rsrc ## addu rdest, $0, rsrc */ String rdest = st.nextToken(); String rsrc = st.nextToken(); stuff.add("addu " + rdest + ", $0, " + rsrc); } else if(instruction.equals("j")) { //check for use of jr String rdest = st.nextToken(); if(parseRegister(rdest) != -128) // compiler ment jr but said j stuff.add("jr " + rdest); else stuff.add(inst); } else // instruction that doesn't need to be fixed { stuff.add(inst); } return stuff; } // returns integer name of register public static byte parseRegister(String reg) { byte regnum = 0; if(reg.equals("$0")) regnum = 0; else if(reg.equals("$zero")) regnum = 0; else if(reg.equals("$1")) regnum = 1; else if(reg.equals("$at")) regnum = 1; else if(reg.equals("$2")) regnum = 2; else if(reg.equals("$v0")) regnum = 2; else if(reg.equals("$3")) regnum = 3; else if(reg.equals("$v1")) regnum = 3; else if(reg.equals("$4")) regnum = 4; else if(reg.equals("$a0")) regnum = 4; else if(reg.equals("$5")) regnum = 5; else if(reg.equals("$a1")) regnum = 5; else if(reg.equals("$6")) regnum = 6; else if(reg.equals("$a2")) regnum = 6; else if(reg.equals("$7")) regnum = 7; else if(reg.equals("$a3")) regnum = 7; else if(reg.equals("$8")) regnum = 8; else if(reg.equals("$t0")) regnum = 8; else if(reg.equals("$9")) regnum = 9; else if(reg.equals("$t1")) regnum = 9; else if(reg.equals("$10")) regnum = 10; else if(reg.equals("$t2")) regnum = 10; else if(reg.equals("$11")) regnum = 11; else if(reg.equals("$t3")) regnum = 11; else if(reg.equals("$12")) regnum = 12; else if(reg.equals("$t4")) regnum = 12; else if(reg.equals("$13")) regnum = 13; else if(reg.equals("$t5")) regnum = 13; else if(reg.equals("$14")) regnum = 14; else if(reg.equals("$t6")) regnum = 14; else if(reg.equals("$15")) regnum = 15; else if(reg.equals("$t7")) regnum = 15; else if(reg.equals("$16")) regnum = 16; else if(reg.equals("$s0")) regnum = 16; else if(reg.equals("$17")) regnum = 17; else if(reg.equals("$s1")) regnum = 17; else if(reg.equals("$18")) regnum = 18; else if(reg.equals("$s2")) regnum = 18; else if(reg.equals("$19")) regnum = 19; else if(reg.equals("$s3")) regnum = 19; else if(reg.equals("$20")) regnum = 20; else if(reg.equals("$s4")) regnum = 20; else if(reg.equals("$21")) regnum = 21; else if(reg.equals("$s5")) regnum = 21; else if(reg.equals("$22")) regnum = 22; else if(reg.equals("$s6")) regnum = 22; else if(reg.equals("$23")) regnum = 23; else if(reg.equals("$s7")) regnum = 23; else if(reg.equals("$24")) regnum = 24; else if(reg.equals("$t8")) regnum = 24; else if(reg.equals("$25")) regnum = 25; else if(reg.equals("$t9")) regnum = 25; else if(reg.equals("$26")) regnum = 26; else if(reg.equals("$k0")) regnum = 26; else if(reg.equals("$27")) regnum = 27; else if(reg.equals("$k1")) regnum = 27; else if(reg.equals("$28")) regnum = 28; else if(reg.equals("$gp")) regnum = 28; else if(reg.equals("$29")) regnum = 29; else if(reg.equals("$sp")) regnum = 29; else if(reg.equals("$30")) regnum = 30; else if(reg.equals("$fp")) regnum = 30; else if(reg.equals("$31")) regnum = 31; else if(reg.equals("$ra")) regnum = 31; else regnum = -128; return regnum; } }