MIPSArchitectureImpl.mesa
Copyright Ó 1992 by Xerox Corporation. All rights reserved.
Katsuyuki Komatsu August 7, 1992 5:11 pm PDT
Jas, October 15, 1992 9:53 am PDT
DIRECTORY
TargetArchitecture,
MIPSArchitecture,
RuntimeError;
MIPSArchitectureImpl: CEDAR PROGRAM
IMPORTS TargetArchitecture, MIPSArchitecture, RuntimeError
EXPORTS MIPSArchitecture
~ {
Code Assembly.
Noop: PUBLIC PROCEDURE []
RETURNS [MIPSArchitecture.MIPSInstruction] ~ {
This is a ``SLL $0, $0, 0'', the recommended noop. 0x00000000.
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] ~ {
Relocates an instruction from the given address to another address.
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];
};
Instruction Classification.
IsDelayedControlTransfer: PUBLIC PROCEDURE [
instruction: MIPSArchitecture.MIPSInstruction]
RETURNS [BOOLEAN] ~ {
Checks whether the instruction at the given pc has a delay slot.
hasDelayInstruction: BOOLEANFALSE;
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[];
A sample noop instruction.
IsNoopInstruction: PUBLIC PROCEDURE [instruction: MIPSArchitecture.MIPSInstruction]
RETURNS [BOOLEAN] ~ {
Checks whether the instruction at the given pc is a noop.
isNoopInstruction: BOOLEAN ~ instruction = noopInstruction;
IF instruction.IsNullMIPSInstruction[] THEN {
ERROR MIPSArchitecture.NullMIPSInstruction;
};
RETURN [isNoopInstruction];
};
NeedsRelocation: PUBLIC PROCEDURE [instruction: MIPSArchitecture.MIPSInstruction]
RETURNS [BOOLEAN] ~ {
Checks whether the instruction at the given pc has pc-relative operands.
needsRelocation: BOOLEANFALSE;
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] ~ {
Checks whether the instruction is a conditional branch instruction.
isBranchInstruction: BOOLEANFALSE;
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] ~ {
Checks whether the instruction is a call instruction.
isCallInstruction: BOOLEANFALSE;
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] ~ {
Checks whether the instruction is a jump instruction.
isJumpInstruction: BOOLEANFALSE;
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];
};
Field accessors for instructions.
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];
};
Field accessors for address.
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];
};
Field assigners for instructions.
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]];
};
Miscellaneous.
IsNullMIPSAddress: PUBLIC PROCEDURE [address: MIPSArchitecture.MIPSAddress]
RETURNS [BOOLEAN] ~ {
Tests if its argument is the null MIPSAddress.
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] ~ {
Tests if its argument is the null MIPSInstruction.
isNullMIPSInstruction: BOOLEAN ~
instruction = MIPSArchitecture.nullMIPSInstruction;
RETURN [isNullMIPSInstruction];
};
NextMIPSInstruction: PUBLIC PROCEDURE [pc: MIPSArchitecture.MIPSAddress]
RETURNS [MIPSArchitecture.MIPSAddress] ~ TRUSTED {
Returns the instruction address after the given one.
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] ~ {
Returns a pointer to the previous instruction.
Yeah for being able to back up in instruction streams, boo for needing to.
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];
IF mipsInstruction.IsNullMIPSInstruction[] THEN {
ERROR MIPSArchitecture.NullMIPSInstruction;
};
RETURN [mipsInstruction];
};
TargetInstructionFromMIPSInstruction: PUBLIC PROCEDURE [
instruction: MIPSArchitecture.MIPSInstruction]
RETURNS [TargetArchitecture.Instruction] ~ {
targetInstruction: TargetArchitecture.Instruction ~ LOOPHOLE[instruction];
IF instruction.IsNullMIPSInstruction[] THEN {
ERROR MIPSArchitecture.NullMIPSInstruction;
};
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];
};
Errors.
CantRelocate: PUBLIC ERROR ~ CODE;
Given for attempts to relocate an instruction too far, etc.
CantReach: PUBLIC ERROR ~ CODE;
Given for attempts to generate pc-relative instructions that don't reach.
NullMIPSAddress: PUBLIC ERROR ~ CODE;
Given during code generation when null addresses are supplied.
NullMIPSInstruction: PUBLIC ERROR ~ CODE;
Given when supplied instruction is the null instruction.
}.