<<>> <> <> <> <> <<>> DIRECTORY TargetArchitecture, MIPSArchitecture, RuntimeError; MIPSArchitectureImpl: CEDAR PROGRAM IMPORTS TargetArchitecture, MIPSArchitecture, RuntimeError EXPORTS MIPSArchitecture ~ { <> Noop: PUBLIC PROCEDURE [] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { <> formatR: MIPSArchitecture.FormatR ~ [ op: MIPSArchitecture.Op.special, rs: MIPSArchitecture.zero, rt: MIPSArchitecture.zero, rd: MIPSArchitecture.zero, sa: 0, opspecial: MIPSArchitecture.OpSpecial.sll]; instruction: MIPSArchitecture.MIPSInstruction ~ LOOPHOLE[formatR]; RETURN [instruction]; }; LW: PUBLIC PROCEDURE [ base: MIPSArchitecture.Register, offset: MIPSArchitecture.Simm16, dest: MIPSArchitecture.Register] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { formatSI: MIPSArchitecture.FormatSI ~ [ op: MIPSArchitecture.Op.lw, rs: base, rt: dest, simm16: offset]; instruction: MIPSArchitecture.MIPSInstruction ~ LOOPHOLE[formatSI]; RETURN [instruction]; }; SW: PUBLIC PROCEDURE [ source: MIPSArchitecture.Register, base: MIPSArchitecture.Register, offset: MIPSArchitecture.Simm16] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { formatSI: MIPSArchitecture.FormatSI ~ [ op: MIPSArchitecture.Op.sw, rs: base, rt: source, simm16: offset]; instruction: MIPSArchitecture.MIPSInstruction ~ LOOPHOLE[formatSI]; RETURN [instruction]; }; LUI: PUBLIC PROCEDURE [ hi: MIPSArchitecture.Imm16, dest: MIPSArchitecture.Register] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { formatI: MIPSArchitecture.FormatI ~ [ op: MIPSArchitecture.Op.lui, rs: dest, rt: dest, imm16: hi]; instruction: MIPSArchitecture.MIPSInstruction ~ LOOPHOLE[formatI]; RETURN [instruction]; }; ORI: PUBLIC PROCEDURE [ source: MIPSArchitecture.Register, constant: MIPSArchitecture.Imm16, dest: MIPSArchitecture.Register] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { formatI: MIPSArchitecture.FormatI ~ [ op: MIPSArchitecture.Op.ori, rs: source, rt: dest, imm16: constant]; instruction: MIPSArchitecture.MIPSInstruction ~ LOOPHOLE[formatI]; RETURN [instruction]; }; ADDIU: PUBLIC PROCEDURE [ source: MIPSArchitecture.Register, constant: MIPSArchitecture.Simm16, dest: MIPSArchitecture.Register] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { formatSI: MIPSArchitecture.FormatSI ~ [ op: MIPSArchitecture.Op.addiu, rs: source, rt: dest, simm16: constant]; instruction: MIPSArchitecture.MIPSInstruction ~ LOOPHOLE[formatSI]; RETURN [instruction]; }; J: PUBLIC PROCEDURE [ pc: MIPSArchitecture.MIPSAddress, to: MIPSArchitecture.MIPSAddress] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { nextPC: MIPSArchitecture.MIPSAddress ~ MIPSArchitecture.NextMIPSInstruction[pc: pc]; nextPCHighOrderBits: MIPSArchitecture.HighOrderBits ~ MIPSArchitecture.GetHighOrderBits[address: nextPC]; toHighOrderBits: MIPSArchitecture.HighOrderBits ~ MIPSArchitecture.GetHighOrderBits[address: to]; disp26: MIPSArchitecture.Disp26 ~ MIPSArchitecture.GetTargetBits[address: to]; formatJ: MIPSArchitecture.FormatJ ~ [ op: MIPSArchitecture.Op.j, disp26: disp26]; instruction: MIPSArchitecture.MIPSInstruction ~ LOOPHOLE[formatJ]; IF pc.IsNullMIPSAddress[] THEN { ERROR MIPSArchitecture.NullMIPSAddress; }; IF to.IsNullMIPSAddress[] THEN { ERROR MIPSArchitecture.NullMIPSAddress; }; IF nextPCHighOrderBits # toHighOrderBits THEN { ERROR MIPSArchitecture.CantReach; }; RETURN [instruction]; }; JAL: PUBLIC PROCEDURE [ pc: MIPSArchitecture.MIPSAddress, to: MIPSArchitecture.MIPSAddress] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { nextPC: MIPSArchitecture.MIPSAddress ~ MIPSArchitecture.NextMIPSInstruction[pc: pc]; nextPCHighOrderBits: MIPSArchitecture.HighOrderBits ~ MIPSArchitecture.GetHighOrderBits[address: nextPC]; toHighOrderBits: MIPSArchitecture.HighOrderBits ~ MIPSArchitecture.GetHighOrderBits[address: to]; disp26: MIPSArchitecture.Disp26 ~ MIPSArchitecture.GetTargetBits[address: to]; formatJ: MIPSArchitecture.FormatJ ~ [ op: MIPSArchitecture.Op.jal, disp26: disp26]; instruction: MIPSArchitecture.MIPSInstruction ~ LOOPHOLE[formatJ]; IF pc.IsNullMIPSAddress[] THEN { ERROR MIPSArchitecture.NullMIPSAddress; }; IF to.IsNullMIPSAddress[] THEN { ERROR MIPSArchitecture.NullMIPSAddress; }; IF nextPCHighOrderBits # toHighOrderBits THEN { ERROR MIPSArchitecture.CantReach; }; RETURN [instruction]; }; JR: PUBLIC PROCEDURE [to: MIPSArchitecture.Register] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { formatR: MIPSArchitecture.FormatR ~ [ op: MIPSArchitecture.Op.special, rs: to, rt: MIPSArchitecture.zero, rd: MIPSArchitecture.zero, sa: 0, opspecial: MIPSArchitecture.OpSpecial.jr]; instruction: MIPSArchitecture.MIPSInstruction ~ LOOPHOLE[formatR]; RETURN [instruction]; }; JALR: PUBLIC PROCEDURE [ returnAddress: MIPSArchitecture.Register _ MIPSArchitecture.ra, to: MIPSArchitecture.Register] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { formatR: MIPSArchitecture.FormatR ~ [ op: MIPSArchitecture.Op.special, rs: to, rt: MIPSArchitecture.zero, rd: returnAddress, sa: 0, opspecial: MIPSArchitecture.OpSpecial.jalr]; instruction: MIPSArchitecture.MIPSInstruction ~ LOOPHOLE[formatR]; RETURN [instruction]; }; RelocateBranch: PROCEDURE [ instruction: MIPSArchitecture.MIPSInstruction, from: MIPSArchitecture.MIPSAddress, to: MIPSArchitecture.MIPSAddress] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { relocated: MIPSArchitecture.MIPSInstruction _ instruction; instructionDisp16: MIPSArchitecture.Disp16 ~ instruction.GetDisp16[]; displacement: TargetArchitecture.Displacement ~ instructionDisp16 * BYTES[MIPSArchitecture.MIPSInstruction]; targetAddress: MIPSArchitecture.MIPSAddress ~ MIPSArchitecture.MIPSAddressFromDisplacement[from, displacement]; relocationDisplacement: TargetArchitecture.Displacement ~ MIPSArchitecture.DisplacementFromMIPSAddresses[here: to, there: targetAddress]; relocationDisp16: MIPSArchitecture.Disp16 ~ relocationDisplacement / BYTES[MIPSArchitecture.MIPSInstruction]; IF relocationDisp16 NOT IN [MIPSArchitecture.firstDisp16..MIPSArchitecture.lastDisp16] THEN { ERROR MIPSArchitecture.CantRelocate; }; IF relocationDisplacement MOD BYTES[MIPSArchitecture.MIPSInstruction] # 0 THEN { ERROR MIPSArchitecture.CantRelocate; }; relocated _ instruction.SetDisp16[disp16: relocationDisp16]; RETURN [relocated]; }; RelocateFormatJ: PROCEDURE [ instruction: MIPSArchitecture.MIPSInstruction, from: MIPSArchitecture.MIPSAddress, to: MIPSArchitecture.MIPSAddress] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { nextFrom: MIPSArchitecture.MIPSAddress ~ MIPSArchitecture.NextMIPSInstruction[pc: from]; nextTo: MIPSArchitecture.MIPSAddress ~ MIPSArchitecture.NextMIPSInstruction[pc: to]; fromHighOrderBits: MIPSArchitecture.HighOrderBits ~ MIPSArchitecture.GetHighOrderBits[address: nextFrom]; toHighOrderBits: MIPSArchitecture.HighOrderBits ~ MIPSArchitecture.GetHighOrderBits[address: nextTo]; IF fromHighOrderBits # toHighOrderBits THEN { ERROR MIPSArchitecture.CantRelocate; }; RETURN [instruction]; }; Relocate: PUBLIC PROCEDURE [ instruction: MIPSArchitecture.MIPSInstruction, from: MIPSArchitecture.MIPSAddress, to: MIPSArchitecture.MIPSAddress] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { <> relocated: MIPSArchitecture.MIPSInstruction _ instruction; IF instruction.IsNullMIPSInstruction[] THEN { RETURN [relocated]; }; IF from.IsNullMIPSAddress[] THEN { ERROR MIPSArchitecture.NullMIPSAddress; }; IF to.IsNullMIPSAddress[] THEN { ERROR MIPSArchitecture.NullMIPSAddress; }; SELECT instruction.GetOp[] FROM special => SELECT instruction.GetOpSpecial[] FROM sll, srl, sra, sllv, srlv, srav => NULL; -- Shift jr => NULL; -- Jump Register jalr => NULL; -- Jump And Link Register syscall => NULL; -- System call exception break => NULL; -- Breakpoint trap sync => NULL; -- Synchronize mfhi, mthi, mflo, mtlo => NULL; -- Manipulate HI, LO registers mult, multu, div, divu => NULL; -- Arithmatic (use HI, LO registers) add, addu, sub, subu, and, or, xor, nor => NULL; -- Arithmatic slt, sltu => NULL; -- Set On Less Than tge, tgeu, tlt, tltu, teq, tne => NULL; -- Trap ENDCASE => ERROR; regimm => SELECT instruction.GetOpRegImm[] FROM bltz => relocated _ RelocateBranch[instruction, from, to]; bgez => relocated _ RelocateBranch[instruction, from, to]; bltzl => relocated _ RelocateBranch[instruction, from, to]; bgezl => relocated _ RelocateBranch[instruction, from, to]; tgei, tgeiu, tlti, tltiu, teqi, tnei => NULL; -- Trap bltzal => relocated _ RelocateBranch[instruction, from, to]; bgezal => relocated _ RelocateBranch[instruction, from, to]; bltzall => relocated _ RelocateBranch[instruction, from, to]; bgezall => relocated _ RelocateBranch[instruction, from, to]; ENDCASE => ERROR; j => relocated _ RelocateFormatJ[instruction, from, to]; jal => relocated _ RelocateFormatJ[instruction, from, to]; beq => relocated _ RelocateBranch[instruction, from, to]; bne => relocated _ RelocateBranch[instruction, from, to]; blez => relocated _ RelocateBranch[instruction, from, to]; bgtz => relocated _ RelocateBranch[instruction, from, to]; addi => NULL; addiu => NULL; slti => NULL; sltiu => NULL; andi => NULL; ori => NULL; xori => NULL; lui => NULL; cop0 => NULL; cop1 => NULL; cop2 => NULL; cop3 => NULL; beql => relocated _ RelocateBranch[instruction, from, to]; bnel => relocated _ RelocateBranch[instruction, from, to]; blezl => relocated _ RelocateBranch[instruction, from, to]; bgtzl => relocated _ RelocateBranch[instruction, from, to]; lb => NULL; lh => NULL; lwl => NULL; lw => NULL; lbu => NULL; lhu => NULL; lwr => NULL; sb => NULL; sh => NULL; swl => NULL; sw => NULL; swr => NULL; cache => NULL; ll => NULL; lwc1 => NULL; lwc2 => NULL; lwc3 => NULL; ldc1 => NULL; ldc2 => NULL; ldc3 => NULL; sc => NULL; swc1 => NULL; swc2 => NULL; swc3 => NULL; sdc1 => NULL; sdc2 => NULL; sdc3 => NULL; ENDCASE => ERROR; RETURN [relocated]; }; <> IsDelayedControlTransfer: PUBLIC PROCEDURE [ instruction: MIPSArchitecture.MIPSInstruction] RETURNS [BOOLEAN] ~ { <> hasDelayInstruction: BOOLEAN _ FALSE; IF instruction.IsNullMIPSInstruction[] THEN { RETURN [hasDelayInstruction]; }; SELECT instruction.GetOp[] FROM special => SELECT instruction.GetOpSpecial[] FROM sll, srl, sra, sllv, srlv, srav => NULL; -- Shift jr => NULL; -- Jump Register jalr => NULL; -- Jump And Link Register syscall => NULL; -- System call exception break => NULL; -- Breakpoint trap sync => NULL; -- Synchronize mfhi, mthi, mflo, mtlo => NULL; -- Manipulate HI, LO registers mult, multu, div, divu => NULL; -- Arithmatic (use HI, LO registers) add, addu, sub, subu, and, or, xor, nor => NULL; -- Arithmatic slt, sltu => NULL; -- Set On Less Than tge, tgeu, tlt, tltu, teq, tne => NULL; -- Trap ENDCASE => ERROR; regimm => SELECT instruction.GetOpRegImm[] FROM bltz => hasDelayInstruction _ TRUE; bgez => hasDelayInstruction _ TRUE; bltzl => hasDelayInstruction _ TRUE; bgezl => hasDelayInstruction _ TRUE; tgei, tgeiu, tlti, tltiu, teqi, tnei => NULL; -- Trap bltzal => hasDelayInstruction _ TRUE; bgezal => hasDelayInstruction _ TRUE; bltzall => hasDelayInstruction _ TRUE; bgezall => hasDelayInstruction _ TRUE; ENDCASE => ERROR; j => hasDelayInstruction _ TRUE; jal => hasDelayInstruction _ TRUE; beq => hasDelayInstruction _ TRUE; bne => hasDelayInstruction _ TRUE; blez => hasDelayInstruction _ TRUE; bgtz => hasDelayInstruction _ TRUE; addi => NULL; addiu => NULL; slti => NULL; sltiu => NULL; andi => NULL; ori => NULL; xori => NULL; lui => NULL; cop0 => NULL; cop1 => NULL; cop2 => NULL; cop3 => NULL; beql => hasDelayInstruction _ TRUE; bnel => hasDelayInstruction _ TRUE; blezl => hasDelayInstruction _ TRUE; bgtzl => hasDelayInstruction _ TRUE; lb => NULL; lh => NULL; lwl => NULL; lw => NULL; lbu => NULL; lhu => NULL; lwr => NULL; sb => NULL; sh => NULL; swl => NULL; sw => NULL; swr => NULL; cache => NULL; ll => NULL; lwc1 => NULL; lwc2 => NULL; lwc3 => NULL; ldc1 => NULL; ldc2 => NULL; ldc3 => NULL; sc => NULL; swc1 => NULL; swc2 => NULL; swc3 => NULL; sdc1 => NULL; sdc2 => NULL; sdc3 => NULL; ENDCASE => ERROR; RETURN [hasDelayInstruction]; }; noopInstruction: MIPSArchitecture.MIPSInstruction ~ MIPSArchitecture.Noop[]; <> IsNoopInstruction: PUBLIC PROCEDURE [instruction: MIPSArchitecture.MIPSInstruction] RETURNS [BOOLEAN] ~ { <> isNoopInstruction: BOOLEAN ~ instruction = noopInstruction; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; RETURN [isNoopInstruction]; }; <<>> NeedsRelocation: PUBLIC PROCEDURE [instruction: MIPSArchitecture.MIPSInstruction] RETURNS [BOOLEAN] ~ { <> needsRelocation: BOOLEAN _ FALSE; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; SELECT instruction.GetOp[] FROM special => SELECT instruction.GetOpSpecial[] FROM sll, srl, sra, sllv, srlv, srav => NULL; -- Shift jr => NULL; -- Jump Register jalr => NULL; -- Jump And Link Register syscall => NULL; -- System call exception break => NULL; -- Breakpoint trap sync => NULL; -- Synchronize mfhi, mthi, mflo, mtlo => NULL; -- Manipulate HI, LO registers mult, multu, div, divu => NULL; -- Arithmatic (use HI, LO registers) add, addu, sub, subu, and, or, xor, nor => NULL; -- Arithmatic slt, sltu => NULL; -- Set On Less Than tge, tgeu, tlt, tltu, teq, tne => NULL; -- Trap ENDCASE => ERROR; regimm => SELECT instruction.GetOpRegImm[] FROM bltz => needsRelocation _ TRUE; bgez => needsRelocation _ TRUE; bltzl => needsRelocation _ TRUE; bgezl => needsRelocation _ TRUE; tgei, tgeiu, tlti, tltiu, teqi, tnei => NULL; -- Trap bltzal => needsRelocation _ TRUE; bgezal => needsRelocation _ TRUE; bltzall => needsRelocation _ TRUE; bgezall => needsRelocation _ TRUE; ENDCASE => ERROR; j => needsRelocation _ TRUE; jal => needsRelocation _ TRUE; beq => needsRelocation _ TRUE; bne => needsRelocation _ TRUE; blez => needsRelocation _ TRUE; bgtz => needsRelocation _ TRUE; addi => NULL; addiu => NULL; slti => NULL; sltiu => NULL; andi => NULL; ori => NULL; xori => NULL; lui => NULL; cop0 => NULL; cop1 => NULL; cop2 => NULL; cop3 => NULL; beql => needsRelocation _ TRUE; bnel => needsRelocation _ TRUE; blezl => needsRelocation _ TRUE; bgtzl => needsRelocation _ TRUE; lb => NULL; lh => NULL; lwl => NULL; lw => NULL; lbu => NULL; lhu => NULL; lwr => NULL; sb => NULL; sh => NULL; swl => NULL; sw => NULL; swr => NULL; cache => NULL; ll => NULL; lwc1 => NULL; lwc2 => NULL; lwc3 => NULL; ldc1 => NULL; ldc2 => NULL; ldc3 => NULL; sc => NULL; swc1 => NULL; swc2 => NULL; swc3 => NULL; sdc1 => NULL; sdc2 => NULL; sdc3 => NULL; ENDCASE => ERROR; RETURN [needsRelocation]; }; IsBranchInstruction: PUBLIC PROCEDURE [ instruction: MIPSArchitecture.MIPSInstruction] RETURNS [BOOLEAN] ~ { <> isBranchInstruction: BOOLEAN _ FALSE; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; SELECT instruction.GetOp[] FROM special => SELECT instruction.GetOpSpecial[] FROM sll, srl, sra, sllv, srlv, srav => NULL; -- Shift jr => NULL; -- Jump Register jalr => NULL; -- Jump And Link Register syscall => NULL; -- System call exception break => NULL; -- Breakpoint trap sync => NULL; -- Synchronize mfhi, mthi, mflo, mtlo => NULL; -- Manipulate HI, LO registers mult, multu, div, divu => NULL; -- Arithmatic (use HI, LO registers) add, addu, sub, subu, and, or, xor, nor => NULL; -- Arithmatic slt, sltu => NULL; -- Set On Less Than tge, tgeu, tlt, tltu, teq, tne => NULL; -- Trap ENDCASE => ERROR; regimm => SELECT instruction.GetOpRegImm[] FROM bltz => isBranchInstruction _ TRUE; bgez => isBranchInstruction _ TRUE; bltzl => isBranchInstruction _ TRUE; bgezl => isBranchInstruction _ TRUE; tgei => NULL; tgeiu => NULL; tlti => NULL; tltiu => NULL; teqi => NULL; tnei => NULL; bltzal => isBranchInstruction _ TRUE; bgezal => isBranchInstruction _ TRUE; bltzall => isBranchInstruction _ TRUE; bgezall => isBranchInstruction _ TRUE; ENDCASE => ERROR; j => isBranchInstruction _ TRUE; jal => isBranchInstruction _ TRUE; beq => isBranchInstruction _ TRUE; bne => isBranchInstruction _ TRUE; blez => isBranchInstruction _ TRUE; bgtz => isBranchInstruction _ TRUE; addi => NULL; addiu => NULL; slti => NULL; sltiu => NULL; andi => NULL; ori => NULL; xori => NULL; lui => NULL; cop0 => NULL; cop1 => NULL; cop2 => NULL; cop3 => NULL; beql => isBranchInstruction _ TRUE; bnel => isBranchInstruction _ TRUE; blezl => isBranchInstruction _ TRUE; bgtzl => isBranchInstruction _ TRUE; lb => NULL; lh => NULL; lwl => NULL; lw => NULL; lbu => NULL; lhu => NULL; lwr => NULL; sb => NULL; sh => NULL; swl => NULL; sw => NULL; swr => NULL; cache => NULL; ll => NULL; lwc1 => NULL; lwc2 => NULL; lwc3 => NULL; ldc1 => NULL; ldc2 => NULL; ldc3 => NULL; sc => NULL; swc1 => NULL; swc2 => NULL; swc3 => NULL; sdc1 => NULL; sdc2 => NULL; sdc3 => NULL; ENDCASE; RETURN [isBranchInstruction]; }; IsCallInstruction: PUBLIC PROCEDURE [instruction: MIPSArchitecture.MIPSInstruction] RETURNS [BOOLEAN] ~ { <> isCallInstruction: BOOLEAN _ FALSE; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; SELECT instruction.GetOp[] FROM special => SELECT instruction.GetOpSpecial[] FROM jalr => isCallInstruction _ TRUE; ENDCASE; jal => isCallInstruction _ TRUE; ENDCASE; RETURN [isCallInstruction]; }; IsJumpInstruction: PUBLIC PROCEDURE [instruction: MIPSArchitecture.MIPSInstruction] RETURNS [BOOLEAN] ~ { <> isJumpInstruction: BOOLEAN _ FALSE; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; SELECT instruction.GetOp[] FROM special => SELECT instruction.GetOpSpecial[] FROM jr => isJumpInstruction _ TRUE; ENDCASE; j => isJumpInstruction _ TRUE; ENDCASE; RETURN [isJumpInstruction]; }; <> GetFormat: PUBLIC PROCEDURE [instruction: MIPSArchitecture.MIPSInstruction] RETURNS [MIPSArchitecture.Format] ~ { format: MIPSArchitecture.Format ~ SELECT instruction.GetOp[] FROM special => MIPSArchitecture.Format.formatR, regimm => MIPSArchitecture.Format.formatSIRegImm, j => MIPSArchitecture.Format.formatJ, jal => MIPSArchitecture.Format.formatJ, beq => MIPSArchitecture.Format.formatSI, bne => MIPSArchitecture.Format.formatSI, blez => MIPSArchitecture.Format.formatSI, bgtz => MIPSArchitecture.Format.formatSI, addi => MIPSArchitecture.Format.formatSI, addiu => MIPSArchitecture.Format.formatSI, slti => MIPSArchitecture.Format.formatSI, sltiu => MIPSArchitecture.Format.formatSI, andi => MIPSArchitecture.Format.formatI, ori => MIPSArchitecture.Format.formatI, xori => MIPSArchitecture.Format.formatI, lui => MIPSArchitecture.Format.formatI, cop0 => MIPSArchitecture.Format.formatR, cop1 => MIPSArchitecture.Format.formatR, cop2 => MIPSArchitecture.Format.formatR, cop3 => MIPSArchitecture.Format.formatR, beql => MIPSArchitecture.Format.formatSI, bnel => MIPSArchitecture.Format.formatSI, blezl => MIPSArchitecture.Format.formatSI, bgtzl => MIPSArchitecture.Format.formatSI, lb => MIPSArchitecture.Format.formatSI, lh => MIPSArchitecture.Format.formatSI, lwl => MIPSArchitecture.Format.formatSI, lw => MIPSArchitecture.Format.formatSI, lbu => MIPSArchitecture.Format.formatSI, lhu => MIPSArchitecture.Format.formatSI, lwr => MIPSArchitecture.Format.formatSI, sb => MIPSArchitecture.Format.formatSI, sh => MIPSArchitecture.Format.formatSI, swl => MIPSArchitecture.Format.formatSI, sw => MIPSArchitecture.Format.formatSI, swr => MIPSArchitecture.Format.formatSI, cache => MIPSArchitecture.Format.formatSI, ll => MIPSArchitecture.Format.formatSI, lwc1 => MIPSArchitecture.Format.formatSI, lwc2 => MIPSArchitecture.Format.formatSI, lwc3 => MIPSArchitecture.Format.formatSI, ldc1 => MIPSArchitecture.Format.formatSI, ldc2 => MIPSArchitecture.Format.formatSI, ldc3 => MIPSArchitecture.Format.formatSI, sc => MIPSArchitecture.Format.formatSI, swc1 => MIPSArchitecture.Format.formatSI, swc2 => MIPSArchitecture.Format.formatSI, swc3 => MIPSArchitecture.Format.formatSI, sdc1 => MIPSArchitecture.Format.formatSI, sdc2 => MIPSArchitecture.Format.formatSI, sdc3 => MIPSArchitecture.Format.formatSI, ENDCASE => ERROR; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; RETURN [format]; }; GetOp: PUBLIC PROCEDURE [instruction: MIPSArchitecture.MIPSInstruction] RETURNS [MIPSArchitecture.Op] ~ { formatI: MIPSArchitecture.FormatI ~ LOOPHOLE[instruction]; op: MIPSArchitecture.Op ~ formatI.op; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; RETURN [op]; }; GetOpSpecial: PUBLIC PROCEDURE [instruction: MIPSArchitecture.MIPSInstruction] RETURNS [MIPSArchitecture.OpSpecial] ~ { formatR: MIPSArchitecture.FormatR ~ LOOPHOLE[instruction]; opspecial: MIPSArchitecture.OpSpecial ~ formatR.opspecial; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; RETURN [opspecial]; }; GetOpRegImm: PUBLIC PROCEDURE [instruction: MIPSArchitecture.MIPSInstruction] RETURNS [MIPSArchitecture.OpRegImm] ~ { formatIRegImm: MIPSArchitecture.FormatIRegImm ~ LOOPHOLE[instruction]; opRegImm: MIPSArchitecture.OpRegImm ~ formatIRegImm.opRegImm; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; RETURN [opRegImm]; }; GetDisp26: PUBLIC PROCEDURE [instruction: MIPSArchitecture.MIPSInstruction] RETURNS [MIPSArchitecture.Disp26] ~ { formatJ: MIPSArchitecture.FormatJ ~ LOOPHOLE[instruction]; disp26: MIPSArchitecture.Disp26 ~ formatJ.disp26; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; RETURN [disp26]; }; GetDisp16: PUBLIC PROCEDURE [instruction: MIPSArchitecture.MIPSInstruction] RETURNS [MIPSArchitecture.Disp16] ~ { formatSI: MIPSArchitecture.FormatSI ~ LOOPHOLE[instruction]; disp16: MIPSArchitecture.Disp16 ~ formatSI.simm16; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; RETURN [disp16]; }; GetImm16: PUBLIC PROCEDURE [instruction: MIPSArchitecture.MIPSInstruction] RETURNS [MIPSArchitecture.Imm16] ~ { formatI: MIPSArchitecture.FormatI ~ LOOPHOLE[instruction]; imm16: MIPSArchitecture.Imm16 ~ formatI.imm16; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; RETURN [imm16]; }; GetSimm16: PUBLIC PROCEDURE [instruction: MIPSArchitecture.MIPSInstruction] RETURNS [MIPSArchitecture.Simm16] ~ { formatSI: MIPSArchitecture.FormatSI ~ LOOPHOLE[instruction]; simm16: MIPSArchitecture.Simm16 ~ formatSI.simm16; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; RETURN [simm16]; }; Hi: PUBLIC PROCEDURE [value: CARD32] RETURNS [MIPSArchitecture.Imm16] ~ { hi: MIPSArchitecture.Imm16 ~ value / (CARD32[MIPSArchitecture.lastImm16] + 1); RETURN [hi]; }; Lo: PUBLIC PROCEDURE [value: CARD32] RETURNS [MIPSArchitecture.Imm16] ~ { lo: MIPSArchitecture.Imm16 ~ value MOD (CARD32[MIPSArchitecture.lastImm16] + 1); RETURN [lo]; }; HiLo: PUBLIC PROCEDURE[hi: MIPSArchitecture.Imm16, lo: MIPSArchitecture.Imm16] RETURNS [CARD32] ~ { hiLo: CARD32 ~ (hi * (CARD32[MIPSArchitecture.lastImm16] + 1)) + lo; RETURN [hiLo]; }; <> GetHighOrderBits: PUBLIC PROCEDURE [ address: MIPSArchitecture.MIPSAddress] RETURNS [MIPSArchitecture.HighOrderBits] ~ { addressFormat: MIPSArchitecture.AddressFormat ~ LOOPHOLE[address]; RETURN [addressFormat.high]; }; GetTargetBits: PUBLIC PROCEDURE [ address: MIPSArchitecture.MIPSAddress] RETURNS [MIPSArchitecture.Disp26] ~ { addressFormat: MIPSArchitecture.AddressFormat ~ LOOPHOLE[address]; RETURN [addressFormat.target]; }; GetTagBits: PUBLIC PROCEDURE [ address: MIPSArchitecture.MIPSAddress] RETURNS [MIPSArchitecture.TagBits] ~ { addressFormat: MIPSArchitecture.AddressFormat ~ LOOPHOLE[address]; RETURN [addressFormat.tag]; }; <> SetDisp16: PUBLIC PROCEDURE [ instruction: MIPSArchitecture.MIPSInstruction, disp16: MIPSArchitecture.Disp16] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { formatSI: MIPSArchitecture.FormatSI _ LOOPHOLE[instruction]; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; formatSI.simm16 _ disp16; RETURN [LOOPHOLE[formatSI]]; }; SetImm16: PUBLIC PROCEDURE [ instruction: MIPSArchitecture.MIPSInstruction, imm16: MIPSArchitecture.Imm16] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { formatI: MIPSArchitecture.FormatI _ LOOPHOLE[instruction]; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; formatI.imm16 _ imm16; RETURN [LOOPHOLE[formatI]]; }; SetSimm16: PUBLIC PROCEDURE [ instruction: MIPSArchitecture.MIPSInstruction, simm16: MIPSArchitecture.Simm16] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { formatSI: MIPSArchitecture.FormatSI _ LOOPHOLE[instruction]; IF instruction.IsNullMIPSInstruction[] THEN { ERROR MIPSArchitecture.NullMIPSInstruction; }; formatSI.simm16 _ simm16; RETURN [LOOPHOLE[formatSI]]; }; <> IsNullMIPSAddress: PUBLIC PROCEDURE [address: MIPSArchitecture.MIPSAddress] RETURNS [BOOLEAN] ~ { <> isNullMIPSAddress: BOOLEAN ~ address = MIPSArchitecture.nullMIPSAddress; RETURN [isNullMIPSAddress]; }; <<>> MIPSAddressFromDisplacement: PUBLIC PROCEDURE [ address: MIPSArchitecture.MIPSAddress, displacement: TargetArchitecture.Displacement] RETURNS [MIPSArchitecture.MIPSAddress] ~ { targetAddress: TargetArchitecture.Address ~ MIPSArchitecture.TargetAddressFromMIPSAddress[mipsAddress: address]; displaced: TargetArchitecture.Address ~ TargetArchitecture.AddressFromDisplacement[ address: targetAddress, displacement: displacement]; mipsDisplaced: MIPSArchitecture.MIPSAddress ~ MIPSArchitecture.MIPSAddressFromTargetAddress[address: displaced]; IF address.IsNullMIPSAddress[] THEN { ERROR MIPSArchitecture.NullMIPSAddress; }; RETURN [mipsDisplaced]; }; DisplacementFromMIPSAddresses: PUBLIC PROCEDURE [ here: MIPSArchitecture.MIPSAddress, there: MIPSArchitecture.MIPSAddress] RETURNS [TargetArchitecture.Displacement] ~ { hereTarget: TargetArchitecture.Address ~ MIPSArchitecture.TargetAddressFromMIPSAddress[mipsAddress: here]; thereTarget: TargetArchitecture.Address ~ MIPSArchitecture.TargetAddressFromMIPSAddress[mipsAddress: there]; displacement: TargetArchitecture.Displacement ~ TargetArchitecture.DisplacementFromAddresses[ here: hereTarget, there: thereTarget]; IF here.IsNullMIPSAddress[] THEN { ERROR MIPSArchitecture.NullMIPSAddress; }; IF there.IsNullMIPSAddress[] THEN { ERROR MIPSArchitecture.NullMIPSAddress; }; RETURN [displacement]; }; IsNullMIPSInstruction: PUBLIC PROCEDURE [ instruction: MIPSArchitecture.MIPSInstruction] RETURNS [BOOLEAN] ~ { <> isNullMIPSInstruction: BOOLEAN ~ instruction = MIPSArchitecture.nullMIPSInstruction; RETURN [isNullMIPSInstruction]; }; <<>> NextMIPSInstruction: PUBLIC PROCEDURE [pc: MIPSArchitecture.MIPSAddress] RETURNS [MIPSArchitecture.MIPSAddress] ~ TRUSTED { <> targetPC: TargetArchitecture.Address ~ MIPSArchitecture.TargetAddressFromMIPSAddress[mipsAddress: pc]; nextInstruction: TargetArchitecture.Address ~ TargetArchitecture.NextInstruction[pc: targetPC]; nextMIPSInstruction: MIPSArchitecture.MIPSAddress ~ MIPSArchitecture.MIPSAddressFromTargetAddress[address: nextInstruction]; IF pc.IsNullMIPSAddress[] THEN { ERROR MIPSArchitecture.NullMIPSAddress; }; RETURN [nextMIPSInstruction]; }; PrevMIPSInstruction: PUBLIC PROCEDURE [pc: MIPSArchitecture.MIPSAddress] RETURNS [MIPSArchitecture.MIPSAddress] ~ { <> <> targetPC: TargetArchitecture.Address ~ MIPSArchitecture.TargetAddressFromMIPSAddress[mipsAddress: pc]; prevInstruction: TargetArchitecture.Address ~ TargetArchitecture.PrevInstruction[pc: targetPC]; prevMIPSInstruction: MIPSArchitecture.MIPSAddress ~ MIPSArchitecture.MIPSAddressFromTargetAddress[address: prevInstruction]; IF pc.IsNullMIPSAddress[] THEN { ERROR MIPSArchitecture.NullMIPSAddress; }; RETURN [prevMIPSInstruction]; }; MIPSAddressFromTargetAddress: PUBLIC PROCEDURE [ address: TargetArchitecture.Address] RETURNS [MIPSArchitecture.MIPSAddress] ~ { mipsAddress: MIPSArchitecture.MIPSAddress ~ LOOPHOLE[address]; IF mipsAddress.IsNullMIPSAddress[] THEN { ERROR MIPSArchitecture.NullMIPSAddress; }; RETURN [mipsAddress]; }; TargetAddressFromMIPSAddress: PUBLIC PROCEDURE [ mipsAddress: MIPSArchitecture.MIPSAddress] RETURNS [TargetArchitecture.Address] ~ { address: TargetArchitecture.Address ~ LOOPHOLE[mipsAddress]; IF mipsAddress.IsNullMIPSAddress[] THEN { ERROR MIPSArchitecture.NullMIPSAddress; }; RETURN [address]; }; MIPSContentsFromTargetContents: PUBLIC PROCEDURE [ contents: TargetArchitecture.Contents] RETURNS [MIPSArchitecture.MIPSContents] ~ { mipsContents: MIPSArchitecture.MIPSContents ~ LOOPHOLE[contents]; RETURN [mipsContents]; }; TargetContentsFromMIPSContents: PUBLIC PROCEDURE [ contents: MIPSArchitecture.MIPSContents] RETURNS [TargetArchitecture.Contents] ~ { targetContents: TargetArchitecture.Contents ~ LOOPHOLE[contents]; RETURN [targetContents]; }; MIPSInstructionFromTargetInstruction: PUBLIC PROCEDURE [ instruction: TargetArchitecture.Instruction] RETURNS [MIPSArchitecture.MIPSInstruction] ~ { mipsInstruction: MIPSArchitecture.MIPSInstruction ~ LOOPHOLE[instruction]; <> <> <<};>> RETURN [mipsInstruction]; }; TargetInstructionFromMIPSInstruction: PUBLIC PROCEDURE [ instruction: MIPSArchitecture.MIPSInstruction] RETURNS [TargetArchitecture.Instruction] ~ { targetInstruction: TargetArchitecture.Instruction ~ LOOPHOLE[instruction]; <> <> <<};>> RETURN [targetInstruction]; }; MIPSRegisterClassFromTargetRegisterClass: PUBLIC PROCEDURE [ registerClass: TargetArchitecture.RegisterClass] RETURNS [MIPSArchitecture.RegisterClass] ~ { mipsRegisterClass: MIPSArchitecture.RegisterClass ~ LOOPHOLE[registerClass]; SELECT mipsRegisterClass FROM none, globals, globalsAndIns, globalsInsAndFloats, globalsInsFloatsOutsAndLocals, all => { NULL; }; ENDCASE => { ERROR RuntimeError.BoundsFault; }; RETURN [mipsRegisterClass]; }; TargetRegisterClassFromMIPSRegisterClass: PUBLIC PROCEDURE [ registerClass: MIPSArchitecture.RegisterClass] RETURNS [TargetArchitecture.RegisterClass] ~ { targetRegisterClass: TargetArchitecture.RegisterClass ~ LOOPHOLE[registerClass]; SELECT registerClass FROM none, globals, globalsAndIns, globalsInsAndFloats, globalsInsFloatsOutsAndLocals, all => { NULL; }; ENDCASE => { ERROR RuntimeError.BoundsFault; }; RETURN [targetRegisterClass]; }; <> CantRelocate: PUBLIC ERROR ~ CODE; <> <<>> CantReach: PUBLIC ERROR ~ CODE; <> <<>> NullMIPSAddress: PUBLIC ERROR ~ CODE; <> <<>> NullMIPSInstruction: PUBLIC ERROR ~ CODE; <> <<>> }. <<>>