use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.
the class Assembler method emitForwardBC.
public ForwardReference emitForwardBC(int cc) {
ForwardReference fr;
if (compiler != null) {
fr = new AssemblerShortBranch(mIP, compiler.spTopOffset);
} else {
fr = new ForwardReference.ShortBranch(mIP);
}
_emitBC(cc, 0);
return fr;
}
use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.
the class Assembler method emitForwardB.
public ForwardReference emitForwardB() {
ForwardReference fr;
if (compiler != null) {
fr = new AssemblerShortBranch(mIP, compiler.spTopOffset);
} else {
fr = new ForwardReference.ShortBranch(mIP);
}
_emitB(0);
return fr;
}
use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.
the class Assembler method emitForwardBL.
public ForwardReference emitForwardBL() {
ForwardReference fr;
if (compiler != null) {
fr = new AssemblerShortBranch(mIP, compiler.spTopOffset);
} else {
fr = new ForwardReference.ShortBranch(mIP);
}
_emitBL(0);
return fr;
}
use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.
the class AssemblerBase method doJCC.
/**
* Emit the given instruction, assuming that
* it is a MIR_CondBranch instruction
* and has a JCC operator
*
* @param inst the instruction to assemble
*/
protected void doJCC(Instruction inst) {
byte cond = getCond(MIR_CondBranch.getCond(inst));
if (isImm(MIR_CondBranch.getTarget(inst))) {
emitJCC_Cond_Imm(cond, getImm(MIR_CondBranch.getTarget(inst)));
} else {
if (VM.VerifyAssertions && !isLabel(MIR_CondBranch.getTarget(inst))) {
throw new OptimizingCompilerException("Unexpected operand " + inst.toString());
}
int sourceLabel = -mcOffsets.getMachineCodeOffset(inst);
int targetLabel = getLabel(MIR_CondBranch.getTarget(inst));
int delta = targetLabel - sourceLabel;
if (VM.VerifyAssertions)
opt_assert(delta >= 0);
if (delta < 10 || (delta < 90 && targetIsClose(inst, -targetLabel))) {
int miStart = mi;
ForwardReference r = new ForwardReference.ShortBranch(mi, targetLabel);
forwardRefs = ForwardReference.enqueue(forwardRefs, r);
setMachineCodes(mi++, (byte) (0x70 + cond));
// leave space for displacement
mi += 1;
if (lister != null)
lister.I(miStart, "J" + CONDITION[cond], 0);
} else {
emitJCC_Cond_Label(cond, targetLabel);
}
}
}
use of org.jikesrvm.compilers.common.assembler.ForwardReference in project JikesRVM by JikesRVM.
the class OutOfLineMachineCode method generateReflectiveMethodInvokerInstructions.
/**
* Machine code for reflective method invocation.
* See also: "Compiler.generateMethodInvocation".
*
*<pre>
* Registers taken at runtime:
* T0 == address of method entrypoint to be called
* T1 == address of gpr registers to be loaded
* T2 == address of fpr registers to be loaded
* T4 == address of spill area in calling frame
*
* Registers returned at runtime:
* standard return value conventions used
*
* Side effects at runtime:
* artificial stackframe created and destroyed
* R0, volatile, and scratch registers destroyed
* </pre>
*/
private static CodeArray generateReflectiveMethodInvokerInstructions() {
Assembler asm = new Assembler(0);
//
// free registers: 0, S0
//
// save...
asm.emitMFLR(GPR.R0);
// ...return address
asm.emitSTAddr(GPR.R0, STACKFRAME_RETURN_ADDRESS_OFFSET.toInt(), FP);
// CTR := start of method code
asm.emitMTCTR(T0);
//
// free registers: 0, S0, T0
//
// create new frame
//
// S0 := old frame pointer
asm.emitMR(S0, FP);
// T0 := number of spill words
asm.emitLIntOffset(T0, T4, ObjectModel.getArrayLengthOffset());
// T4 -= 4 (predecrement, ie. T4 + 4 is &spill[0] )
asm.emitADDI(T4, -BYTES_IN_ADDRESS, T4);
int spillLoopLabel = asm.getMachineCodeIndex();
// T0 -= 1 (and set CR)
asm.emitADDICr(T0, T0, -1);
// if T0 < 0 then break
ForwardReference fr1 = asm.emitForwardBC(LT);
// R0 := *(T4 += 4)
asm.emitLAddrU(GPR.R0, BYTES_IN_ADDRESS, T4);
// put one word of spill area
asm.emitSTAddrU(GPR.R0, -BYTES_IN_ADDRESS, FP);
// goto spillLoop:
asm.emitB(spillLoopLabel);
fr1.resolve(asm);
// allocate frame header and save old fp
asm.emitSTAddrU(S0, -STACKFRAME_HEADER_SIZE, FP);
asm.emitLVAL(T0, INVISIBLE_METHOD_ID);
// set method id
asm.emitSTWoffset(T0, FP, STACKFRAME_METHOD_ID_OFFSET);
//
// free registers: 0, S0, T0, T4
//
// load up fprs
//
ForwardReference setupFPRLoader = asm.emitForwardBL();
for (int i = LAST_VOLATILE_FPR.value(); i >= FIRST_VOLATILE_FPR.value(); --i) {
// FPRi := fprs[i]
asm.emitLFDU(FPR.lookup(i), BYTES_IN_DOUBLE, T2);
}
//
// free registers: 0, S0, T0, T2, T4
//
// load up gprs
//
ForwardReference setupGPRLoader = asm.emitForwardBL();
for (int i = LAST_VOLATILE_GPR.value(); i >= FIRST_VOLATILE_GPR.value(); --i) {
// GPRi := gprs[i]
asm.emitLAddrU(GPR.lookup(i), BYTES_IN_ADDRESS, S0);
}
//
// free registers: 0, S0
//
// invoke method
//
// branch and link to method code
asm.emitBCCTRL();
// emit method epilog
//
// restore caller's frame
asm.emitLAddr(FP, 0, FP);
// pick up return address
asm.emitLAddr(S0, STACKFRAME_RETURN_ADDRESS_OFFSET.toInt(), FP);
//
asm.emitMTLR(S0);
// return to caller
asm.emitBCLR();
setupFPRLoader.resolve(asm);
// T4 := address of first fpr load instruction
asm.emitMFLR(T4);
// T0 := number of fprs to be loaded
asm.emitLIntOffset(T0, T2, ObjectModel.getArrayLengthOffset());
asm.emitADDI(T4, VOLATILE_FPRS << LG_INSTRUCTION_WIDTH, // T4 := address of first instruction following fpr loads
T4);
// T0 := number of bytes of fpr load instructions
asm.emitSLWI(T0, T0, LG_INSTRUCTION_WIDTH);
// T4 := address of instruction for highest numbered fpr to be loaded
asm.emitSUBFC(T4, T0, T4);
// LR := """
asm.emitMTLR(T4);
// predecrement fpr index (to prepare for update instruction)
asm.emitADDI(T2, -BYTES_IN_DOUBLE, T2);
// branch to fpr loading instructions
asm.emitBCLR();
setupGPRLoader.resolve(asm);
// T4 := address of first gpr load instruction
asm.emitMFLR(T4);
// T0 := number of gprs to be loaded
asm.emitLIntOffset(T0, T1, ObjectModel.getArrayLengthOffset());
asm.emitADDI(T4, VOLATILE_GPRS << LG_INSTRUCTION_WIDTH, // T4 := address of first instruction following gpr loads
T4);
// T0 := number of bytes of gpr load instructions
asm.emitSLWI(T0, T0, LG_INSTRUCTION_WIDTH);
// T4 := address of instruction for highest numbered gpr to be loaded
asm.emitSUBFC(T4, T0, T4);
// LR := """
asm.emitMTLR(T4);
// predecrement gpr index (to prepare for update instruction)
asm.emitADDI(S0, -BYTES_IN_ADDRESS, T1);
// branch to gpr loading instructions
asm.emitBCLR();
return asm.getMachineCodes();
}
Aggregations