InstallNormalManger:
PROCEDURE [
address: BreakWorldArchitecture.Address,
manger: BreakWorldArchitecture.Address,
patchCode: BreakWorldArchitecture.Address]
RETURNS [] ~ {
errorCode: SPARCManger.ErrorCode ← SPARCManger.nullErrorCode;
errorMessage: SPARCManger.ErrorMessage ← SPARCManger.nullErrorMessage;
instructionAddress: SPARCArchitecture.SPARCAddress ~
SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: address];
mangerSPARCAddress: SPARCArchitecture.SPARCAddress ~
SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: manger];
normalManger: SPARCManger.NormalManger;
{
instruction: SPARCArchitecture.SPARCInstruction ~
SPARCBreakWorldUtilities.SPARCInstructionFromBreakWorldAddress[address: address];
instructionAddress: SPARCArchitecture.SPARCAddress ~
SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: address];
sheepAddress: SPARCArchitecture.SPARCAddress ~
SPARCArchitecture.SPARCAddressFromDisplacement[
address: mangerSPARCAddress, displacement: SheepOffset[]];
relocated: SPARCArchitecture.SPARCInstruction ~ SPARCArchitecture.Relocate[
instruction: instruction,
from: instructionAddress,
to: sheepAddress
! SPARCArchitecture.CantRelocate => {
errorCode ← $CantRelocate;
errorMessage ← "Cannot relocate instruction at breakpoint address";
GO TO Cannot;
}];
Is this the only transformation of the instruction that's required
normalManger.sheep ← relocated;
BreakWorldArchitecture.PokeInstruction[
pc: manger,
displacement: SheepOffset[],
instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[
instruction: normalManger.sheep]];
EXITS
Cannot => {
ERROR CantInstall[code: errorCode, message: errorMessage];
};
};
{
nextInstructionAddress: SPARCArchitecture.SPARCAddress ~
SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[
address: BreakWorldArchitecture.NextInstruction[pc: address]];
normalContinueAddress: SPARCArchitecture.SPARCAddress ~
SPARCArchitecture.SPARCAddressFromDisplacement[
address: mangerSPARCAddress, displacement: NormalContinueOffset[]];
normalManger.normalContinue ← SPARCArchitecture.BAa[
pc: normalContinueAddress, to: nextInstructionAddress];
BreakWorldArchitecture.PokeInstruction[
pc: manger,
displacement: NormalContinueOffset[],
instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[
instruction: normalManger.normalContinue]];
};
{
normalManger.normalNoop ← SPARCArchitecture.Noop[];
BreakWorldArchitecture.PokeInstruction[
pc: manger,
displacement: NormalNoopOffset[],
instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[
instruction: normalManger.normalNoop]];
};
{
normalManger.tag ← SPARCArchitecture.Sethi[
hi: ORD[SPARCManger.MangerVariant.normal],
dest: SPARCArchitecture.Register.global0];
BreakWorldArchitecture.PokeInstruction[
pc: manger,
displacement: TagOffset[],
instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[
instruction: normalManger.tag]];
};
{
link the patch into the running code.
patchSPARCAddress: SPARCArchitecture.SPARCAddress ~
SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: patchCode];
instruction: SPARCArchitecture.SPARCInstruction ~ SPARCArchitecture.BAa[
pc: instructionAddress, to: patchSPARCAddress];
BreakWorldArchitecture.PokeInstruction[
pc: address,
instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[
instruction: instruction]];
This better be atomic. Else you have a race in smashed memory!
};
};
InstallBranchManger:
PROCEDURE [
address: BreakWorldArchitecture.Address,
manger: BreakWorldArchitecture.Address,
patchCode: BreakWorldArchitecture.Address]
RETURNS [] ~ {
errorCode: SPARCManger.ErrorCode ← SPARCManger.nullErrorCode;
errorMessage: SPARCManger.ErrorMessage ← SPARCManger.nullErrorMessage;
instructionAddress: SPARCArchitecture.SPARCAddress ~
SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: address];
mangerSPARCAddress: SPARCArchitecture.SPARCAddress ~
SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: manger];
branchManger: SPARCManger.BranchManger;
branchDelayBreakWorldAddress: BreakWorldArchitecture.Address ~ BreakWorldArchitecture.NextInstruction[
pc: address];
branchContinueBreakWorldAddress: BreakWorldArchitecture.Address ~
BreakWorldArchitecture.NextInstruction[pc: branchDelayBreakWorldAddress];
{
instruction: SPARCArchitecture.SPARCInstruction ~
SPARCBreakWorldUtilities.SPARCInstructionFromBreakWorldAddress[address: address];
instructionAddress: SPARCArchitecture.SPARCAddress ~
SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: address];
dctiAddress: SPARCArchitecture.SPARCAddress ~
SPARCArchitecture.SPARCAddressFromDisplacement[
address: mangerSPARCAddress, displacement: DctiOffset[]];
relocated: SPARCArchitecture.SPARCInstruction ~ SPARCArchitecture.Relocate[
instruction: instruction,
from: instructionAddress,
to: dctiAddress
! SPARCArchitecture.CantRelocate => {
errorCode ← $CantRelocate;
errorMessage ← "Cannot relocate instruction at breakpoint address";
GO TO Cannot;
}];
Is this the only transformation of the instruction that's required
branchManger.dcti ← relocated;
BreakWorldArchitecture.PokeInstruction[
pc: manger,
displacement: DctiOffset[],
instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[
instruction: branchManger.dcti]];
EXITS
Cannot => {
ERROR CantInstall[code: errorCode, message: errorMessage];
};
};
{
branchDelayInstructionAddress: SPARCArchitecture.SPARCAddress ~
SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[
address: branchDelayBreakWorldAddress];
branchDelayAddress: SPARCArchitecture.SPARCAddress ~
SPARCArchitecture.SPARCAddressFromDisplacement[
address: mangerSPARCAddress, displacement: BranchDelayOffset[]];
branchDelayInstruction: SPARCArchitecture.SPARCInstruction ~
SPARCBreakWorldUtilities.SPARCInstructionFromBreakWorldAddress[
address: branchDelayBreakWorldAddress];
relocatedBranchDelayInstruction: SPARCArchitecture.SPARCInstruction ~
SPARCArchitecture.Relocate[
instruction: branchDelayInstruction,
from: branchDelayInstructionAddress,
to: branchDelayAddress
! SPARCArchitecture.CantRelocate => {
errorCode ← $CantRelocate;
errorMessage ←
"Cannot relocate instruction in delay slot of breakpoint address";
GO TO Cannot;
}];
branchManger.branchDelay ← relocatedBranchDelayInstruction;
BreakWorldArchitecture.PokeInstruction[
pc: manger,
displacement: BranchDelayOffset[],
instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[
instruction: branchManger.branchDelay]];
EXITS
Cannot => {
ERROR CantInstall[code: errorCode, message: errorMessage];
};
};
{
branchContinueInstructionAddress: SPARCArchitecture.SPARCAddress ~
SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[
address: branchContinueBreakWorldAddress];
branchContinueAddress: SPARCArchitecture.SPARCAddress ~
SPARCArchitecture.SPARCAddressFromDisplacement[
address: mangerSPARCAddress, displacement: BranchContinueOffset[]];
branchManger.branchContinue ← SPARCArchitecture.BAa[
pc: branchContinueAddress, to: branchContinueInstructionAddress];
BreakWorldArchitecture.PokeInstruction[
pc: manger,
displacement: BranchContinueOffset[],
instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[
instruction: branchManger.branchContinue]];
};
{
branchManger.tag ← SPARCArchitecture.Sethi[
hi: ORD[SPARCManger.MangerVariant.branch],
dest: SPARCArchitecture.Register.global0];
BreakWorldArchitecture.PokeInstruction[
pc: manger,
displacement: TagOffset[],
instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[
instruction: branchManger.tag]];
};
{
link the patch into the running code.
patchSPARCAddress: SPARCArchitecture.SPARCAddress ~
SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: patchCode];
instruction: SPARCArchitecture.SPARCInstruction ~ SPARCArchitecture.BAa[
pc: instructionAddress, to: patchSPARCAddress];
BreakWorldArchitecture.PokeInstruction[
pc: address,
instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[
instruction: instruction]];
This better be atomic. Else you have a race in smashed memory!
};
};
InstallCallManger:
PROCEDURE [
address: BreakWorldArchitecture.Address,
manger: BreakWorldArchitecture.Address,
patchCode: BreakWorldArchitecture.Address]
RETURNS [] ~ {
callManger: SPARCManger.CallManger;
instruction: SPARCArchitecture.SPARCInstruction ~
SPARCBreakWorldUtilities.SPARCInstructionFromBreakWorldAddress[address: address];
instructionTargetAddress: TargetArchitecture.Address ~
BreakWorldArchitecture.TargetAddressFromBreakWorldAddress[address: address];
instructionAddress: SPARCArchitecture.SPARCAddress ~
SPARCArchitecture.SPARCAddressFromTargetAddress[address: instructionTargetAddress];
instructionDisp30: SPARCArchitecture.Disp30 ~ instruction.GetDisp30[];
byteDisplacement: TargetArchitecture.Displacement ~
instructionDisp30 * BYTES[SPARCArchitecture.SPARCInstruction];
destination: TargetArchitecture.Address ~ TargetArchitecture.AddressFromDisplacement[
address: instructionTargetAddress, displacement: byteDisplacement];
mangerSPARCAddress: SPARCArchitecture.SPARCAddress ~
SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: manger];
{
callManger.callAddrHi ← SPARCArchitecture.Sethi[
hi: SPARCArchitecture.Hi[value: LOOPHOLE[destination]],
dest: SPARCArchitecture.Register.global1];
BreakWorldArchitecture.PokeInstruction[
pc: manger,
displacement: CallAddrHiOffset[],
instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[
instruction: callManger.callAddrHi]];
};
{
callManger.callJmp ← SPARCArchitecture.JmplConst[
source: SPARCArchitecture.Register.global1,
constant: SPARCArchitecture.Lo[value: LOOPHOLE[destination]],
dest: SPARCArchitecture.Register.global0];
BreakWorldArchitecture.PokeInstruction[
pc: manger,
displacement: CallJmpOffset[],
instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[
instruction: callManger.callJmp]];
};
{
callManger.callNoop ← SPARCArchitecture.Noop[];
BreakWorldArchitecture.PokeInstruction[
pc: manger,
displacement: CallNoopOffset[],
instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[
instruction: callManger.callNoop]];
};
{
callManger.tag ← SPARCArchitecture.Sethi[
hi: ORD[SPARCManger.MangerVariant.call],
dest: SPARCArchitecture.Register.global0];
BreakWorldArchitecture.PokeInstruction[
pc: manger,
displacement: TagOffset[],
instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[
instruction: callManger.tag]];
};
{
link the patch into the running code.
patchSPARCAddress: SPARCArchitecture.SPARCAddress ~
SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: patchCode];
instruction: SPARCArchitecture.SPARCInstruction ~ SPARCArchitecture.Call[
pc: instructionAddress, to: patchSPARCAddress];
BreakWorldArchitecture.PokeInstruction[
pc: address,
instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[
instruction: instruction]];
This better be atomic. Else you have a race in smashed memory!
};
};
UninstallCall:
PROCEDURE [
address: BreakWorldArchitecture.Address,
manger: BreakWorldArchitecture.Address] ~ {
errorCode: SPARCManger.ErrorCode ← SPARCManger.nullErrorCode;
errorMessage: SPARCManger.ErrorMessage ← SPARCManger.nullErrorMessage;
callAddrHiInstruction: SPARCArchitecture.SPARCInstruction ~
SPARCBreakWorldUtilities.SPARCInstructionFromBreakWorldAddress[
address: manger, displacement: CallAddrHiOffset[]];
callAddrHi: SPARCArchitecture.Imm22 ~ callAddrHiInstruction.GetImm22[];
callAddrLoInstruction: SPARCArchitecture.SPARCInstruction ~
SPARCBreakWorldUtilities.SPARCInstructionFromBreakWorldAddress[
address: manger, displacement: CallJmpOffset[]];
callAddrLo: SPARCArchitecture.Simm13 ~ callAddrLoInstruction.GetSimm13[];
callAddr: SPARCArchitecture.SPARCAddress ~
LOOPHOLE[SPARCArchitecture.HiLo[hi: callAddrHi, lo: callAddrLo]];
instructionAddress: SPARCArchitecture.SPARCAddress ~
SPARCBreakWorldUtilities.SPARCAddressFromBreakWorldAddress[address: address];
callInstruction: SPARCArchitecture.SPARCInstruction ~ SPARCArchitecture.Call[
pc: instructionAddress, to: callAddr];
BreakWorldArchitecture.PokeInstruction[
pc: address,
instruction: SPARCArchitecture.TargetInstructionFromSPARCInstruction[
instruction: callInstruction]];
This better be atomic. Else you have a race in smashed code!
RETURN;
};
Manger offsets:
SheepOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
offset: TargetArchitecture.Displacement ← TargetArchitecture.nullDisplacement;
manger: SPARCManger.NormalManger;
mangerAddress: LONG POINTER TO SPARCManger.NormalManger ~ @manger;
mangerCard: CARD32 ~ LOOPHOLE[mangerAddress];
sheepAddress:
LONG
POINTER
TO SPARCArchitecture.SPARCInstruction ~
@manger.sheep;
sheepCard: CARD32 ~ LOOPHOLE[sheepAddress];
offset ← (sheepCard - mangerCard) * BYTES[UNIT];
RETURN [offset];
};
NormalContinueOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
offset: TargetArchitecture.Displacement ← TargetArchitecture.nullDisplacement;
manger: SPARCManger.NormalManger;
mangerAddress: LONG POINTER TO SPARCManger.NormalManger ~ @manger;
mangerCard: CARD32 ~ LOOPHOLE[mangerAddress];
normalContinueAddress:
LONG
POINTER
TO SPARCArchitecture.SPARCInstruction ~
@manger.normalContinue;
normalContinueCard: CARD32 ~ LOOPHOLE[normalContinueAddress];
offset ← (normalContinueCard - mangerCard) * BYTES[UNIT];
RETURN [offset];
};
NormalNoopOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
offset: TargetArchitecture.Displacement ← TargetArchitecture.nullDisplacement;
manger: SPARCManger.NormalManger;
mangerAddress: LONG POINTER TO SPARCManger.NormalManger ~ @manger;
mangerCard: CARD32 ~ LOOPHOLE[mangerAddress];
normalNoopAddress:
LONG
POINTER
TO SPARCArchitecture.SPARCInstruction ~
@manger.normalNoop;
normalNoopCard: CARD32 ~ LOOPHOLE[normalNoopAddress];
offset ← (normalNoopCard - mangerCard) * BYTES[UNIT];
RETURN [offset];
};
TagOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
offset: TargetArchitecture.Displacement ← TargetArchitecture.nullDisplacement;
manger: SPARCManger.NormalManger;
mangerAddress: LONG POINTER TO SPARCManger.NormalManger ~ @manger;
mangerCard: CARD32 ~ LOOPHOLE[mangerAddress];
tagAddress:
LONG
POINTER
TO SPARCArchitecture.SPARCInstruction ~
@manger.tag;
tagCard: CARD32 ~ LOOPHOLE[tagAddress];
offset ← (tagCard - mangerCard) * BYTES[UNIT];
RETURN [offset];
};
DctiOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
offset: TargetArchitecture.Displacement ← TargetArchitecture.nullDisplacement;
manger: SPARCManger.BranchManger;
mangerAddress: LONG POINTER TO SPARCManger.BranchManger ~ @manger;
mangerCard: CARD32 ~ LOOPHOLE[mangerAddress];
dctiAddress:
LONG
POINTER
TO SPARCArchitecture.SPARCInstruction ~
@manger.dcti;
dctiCard: CARD32 ~ LOOPHOLE[dctiAddress];
offset ← (dctiCard - mangerCard) * BYTES[UNIT];
RETURN [offset];
};
BranchDelayOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
offset: TargetArchitecture.Displacement ← TargetArchitecture.nullDisplacement;
manger: SPARCManger.BranchManger;
mangerAddress: LONG POINTER TO SPARCManger.BranchManger ~ @manger;
mangerCard: CARD32 ~ LOOPHOLE[mangerAddress];
branchDelayAddress:
LONG
POINTER
TO SPARCArchitecture.SPARCInstruction ~
@manger.branchDelay;
branchDelayCard: CARD32 ~ LOOPHOLE[branchDelayAddress];
offset ← (branchDelayCard - mangerCard) * BYTES[UNIT];
RETURN [offset];
};
BranchContinueOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
offset: TargetArchitecture.Displacement ← TargetArchitecture.nullDisplacement;
manger: SPARCManger.BranchManger;
mangerAddress: LONG POINTER TO SPARCManger.BranchManger ~ @manger;
mangerCard: CARD32 ~ LOOPHOLE[mangerAddress];
branchContinueAddress:
LONG
POINTER
TO SPARCArchitecture.SPARCInstruction ~
@manger.branchContinue;
branchContinueCard: CARD32 ~ LOOPHOLE[branchContinueAddress];
offset ← (branchContinueCard - mangerCard) * BYTES[UNIT];
RETURN [offset];
};
CallAddrHiOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
offset: TargetArchitecture.Displacement ← TargetArchitecture.nullDisplacement;
manger: SPARCManger.CallManger;
mangerAddress: LONG POINTER TO SPARCManger.CallManger ~ @manger;
mangerCard: CARD32 ~ LOOPHOLE[mangerAddress];
callAddrHiAddress:
LONG
POINTER
TO SPARCArchitecture.SPARCInstruction ~
@manger.callAddrHi;
callAddrHiCard: CARD32 ~ LOOPHOLE[callAddrHiAddress];
offset ← (callAddrHiCard - mangerCard) * BYTES[UNIT];
RETURN [offset];
};
CallJmpOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
offset: TargetArchitecture.Displacement ← TargetArchitecture.nullDisplacement;
manger: SPARCManger.CallManger;
mangerAddress: LONG POINTER TO SPARCManger.CallManger ~ @manger;
mangerCard: CARD32 ~ LOOPHOLE[mangerAddress];
callJmpAddress:
LONG
POINTER
TO SPARCArchitecture.SPARCInstruction ~
@manger.callJmp;
callJmpCard: CARD32 ~ LOOPHOLE[callJmpAddress];
offset ← (callJmpCard - mangerCard) * BYTES[UNIT];
RETURN [offset];
};
CallNoopOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
offset: TargetArchitecture.Displacement ← TargetArchitecture.nullDisplacement;
manger: SPARCManger.CallManger;
mangerAddress: LONG POINTER TO SPARCManger.CallManger ~ @manger;
mangerCard: CARD32 ~ LOOPHOLE[mangerAddress];
callNoopAddress:
LONG
POINTER
TO SPARCArchitecture.SPARCInstruction ~
@manger.callNoop;
callNoopCard: CARD32 ~ LOOPHOLE[callNoopAddress];
offset ← (callNoopCard - mangerCard) * BYTES[UNIT];
RETURN [offset];
};
JmplO7JmpOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
offset: TargetArchitecture.Displacement ← TargetArchitecture.nullDisplacement;
manger: SPARCManger.JmplO7Manger;
mangerAddress: LONG POINTER TO SPARCManger.JmplO7Manger ~ @manger;
mangerCard: CARD32 ~ LOOPHOLE[mangerAddress];
jmplO7JmpAddress:
LONG
POINTER
TO SPARCArchitecture.SPARCInstruction ~
@manger.jmplO7Jmp;
jmplO7JmpCard: CARD32 ~ LOOPHOLE[jmplO7JmpAddress];
offset ← (jmplO7JmpCard - mangerCard) * BYTES[UNIT];
RETURN [offset];
};
JmplO7NoopOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
offset: TargetArchitecture.Displacement ← TargetArchitecture.nullDisplacement;
manger: SPARCManger.JmplO7Manger;
mangerAddress: LONG POINTER TO SPARCManger.JmplO7Manger ~ @manger;
mangerCard: CARD32 ~ LOOPHOLE[mangerAddress];
jmplO7NoopAddress:
LONG
POINTER
TO SPARCArchitecture.SPARCInstruction ~
@manger.jmplO7Noop;
jmplO7NoopCard: CARD32 ~ LOOPHOLE[jmplO7NoopAddress];
offset ← (jmplO7NoopCard - mangerCard) * BYTES[UNIT];
RETURN [offset];
};
JmplO7PadOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
offset: TargetArchitecture.Displacement ← TargetArchitecture.nullDisplacement;
manger: SPARCManger.JmplO7Manger;
mangerAddress: LONG POINTER TO SPARCManger.JmplO7Manger ~ @manger;
mangerCard: CARD32 ~ LOOPHOLE[mangerAddress];
jmplO7PadAddress:
LONG
POINTER
TO SPARCArchitecture.SPARCInstruction ~
@manger.jmplO7Pad;
jmplO7PadCard: CARD32 ~ LOOPHOLE[jmplO7PadAddress];
offset ← (jmplO7PadCard - mangerCard) * BYTES[UNIT];
RETURN [offset];
};
JmplG0JmpOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
offset: TargetArchitecture.Displacement ← TargetArchitecture.nullDisplacement;
manger: SPARCManger.JmplG0Manger;
mangerAddress: LONG POINTER TO SPARCManger.JmplG0Manger ~ @manger;
mangerCard: CARD32 ~ LOOPHOLE[mangerAddress];
jmplG0JmpAddress:
LONG
POINTER
TO SPARCArchitecture.SPARCInstruction ~
@manger.jmplG0Jmp;
jmplG0JmpCard: CARD32 ~ LOOPHOLE[jmplG0JmpAddress];
offset ← (jmplG0JmpCard - mangerCard) * BYTES[UNIT];
RETURN [offset];
};
JmplG0DelayOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
offset: TargetArchitecture.Displacement ← TargetArchitecture.nullDisplacement;
manger: SPARCManger.JmplG0Manger;
mangerAddress: LONG POINTER TO SPARCManger.JmplG0Manger ~ @manger;
mangerCard: CARD32 ~ LOOPHOLE[mangerAddress];
jmplG0DelayAddress:
LONG
POINTER
TO SPARCArchitecture.SPARCInstruction ~
@manger.jmplG0Delay;
jmplG0DelayCard: CARD32 ~ LOOPHOLE[jmplG0DelayAddress];
offset ← (jmplG0DelayCard - mangerCard) * BYTES[UNIT];
RETURN [offset];
};
JmplG0PadOffset:
PROCEDURE []
RETURNS [TargetArchitecture.Displacement] ~
TRUSTED {
offset: TargetArchitecture.Displacement ← TargetArchitecture.nullDisplacement;
manger: SPARCManger.JmplG0Manger;
mangerAddress: LONG POINTER TO SPARCManger.JmplG0Manger ~ @manger;
mangerCard: CARD32 ~ LOOPHOLE[mangerAddress];
jmplG0PadAddress:
LONG
POINTER
TO SPARCArchitecture.SPARCInstruction ~
@manger.jmplG0Pad;
jmplG0PadCard: CARD32 ~ LOOPHOLE[jmplG0PadAddress];
offset ← (jmplG0PadCard - mangerCard) * BYTES[UNIT];
RETURN [offset];
};