use of org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand in project JikesRVM by JikesRVM.
the class BURS_Helpers method SYSCALL.
/**
* Expansion of SYSCALL. Expand longs registers into pairs of int registers.
*
* @param s the instruction to expand
* @param address the operand containing the target address
*/
protected final void SYSCALL(Instruction s, Operand address) {
burs.ir.setHasSysCall(true);
if (VM.BuildFor32Addr) {
// Step 1: Find out how many parameters we're going to have.
int numParams = Call.getNumberOfParams(s);
int longParams = 0;
for (int pNum = 0; pNum < numParams; pNum++) {
if (Call.getParam(s, pNum).getType().isLongType()) {
longParams++;
}
}
// Step 2: Figure out what the result and result2 values will be.
RegisterOperand result = Call.getResult(s);
RegisterOperand result2 = null;
// NOTE: C callee returns longs little endian!
if (result != null && result.getType().isLongType()) {
result.setType(TypeReference.Int);
result2 = result;
result = new RegisterOperand(regpool.getSecondReg(result.getRegister()), TypeReference.Int);
}
// Step 3: Mutate the Call to an MIR_Call.
// Note MIR_Call and Call have a different number of fixed
// arguments, so some amount of copying is required.
Operand[] params = new Operand[numParams];
for (int i = 0; i < numParams; i++) {
params[i] = Call.getParam(s, i);
}
MIR_Call.mutate(s, IA32_SYSCALL, result, result2, address, Call.getMethod(s), numParams + longParams);
for (int paramIdx = 0, mirCallIdx = 0; paramIdx < numParams; ) {
Operand param = params[paramIdx++];
if (param instanceof RegisterOperand) {
// NOTE: longs passed little endian to C callee!
RegisterOperand rparam = (RegisterOperand) param;
if (rparam.getType().isLongType()) {
rparam.setType(TypeReference.Int);
MIR_Call.setParam(s, mirCallIdx++, new RegisterOperand(regpool.getSecondReg(rparam.getRegister()), TypeReference.Int));
}
MIR_Call.setParam(s, mirCallIdx++, param);
} else if (param instanceof LongConstantOperand) {
long value = ((LongConstantOperand) param).value;
int valueHigh = (int) (value >> 32);
int valueLow = (int) (value & 0xffffffff);
// NOTE: longs passed little endian to C callee!
MIR_Call.setParam(s, mirCallIdx++, IC(valueLow));
MIR_Call.setParam(s, mirCallIdx++, IC(valueHigh));
} else {
MIR_Call.setParam(s, mirCallIdx++, param);
}
}
} else {
MIR_Call.mutate(s, IA32_SYSCALL, Call.getResult(s), null, address, Call.getMethod(s), Call.getNumberOfParams(s));
}
// emit the call instruction.
EMIT(s);
}
use of org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand in project JikesRVM by JikesRVM.
the class BURS_MemOp_Helpers method augmentAddress.
protected final void augmentAddress(Operand op) {
if (VM.VerifyAssertions)
VM._assert(AddrStack != null, "No address to augment");
if (op.isRegister()) {
RegisterOperand rop = op.asRegister();
if (AddrStack.base == null) {
AddrStack.base = rop;
} else if (AddrStack.index == null) {
if (VM.VerifyAssertions)
VM._assert(AddrStack.scale == (byte) 0);
AddrStack.index = rop;
} else {
throw new OptimizingCompilerException("three base registers in address");
}
} else {
if (VM.fullyBooted) {
if (VM.BuildFor64Addr && op instanceof IntConstantOperand)
throw new OptimizingCompilerException("augmenting int to address in 64bit code");
if (VM.BuildFor32Addr && op instanceof LongConstantOperand)
throw new OptimizingCompilerException("augmenting long to address in 32bit code");
}
long dispTemp = op instanceof LongConstantOperand ? ((LongConstantOperand) op).value : ((IntConstantOperand) op).value;
if (VM.VerifyAssertions && VM.BuildFor32Addr)
opt_assert(fits(dispTemp, 32));
Offset disp = Offset.fromLong(dispTemp);
AddrStack.displacement = AddrStack.displacement.plus(disp);
}
}
Aggregations