use of org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand in project JikesRVM by JikesRVM.
the class NormalizeConstants method asImmediateOrRegLong.
static Operand asImmediateOrRegLong(Operand addr, Instruction s, IR ir, boolean signed) {
if (VM.BuildFor64Addr && (addr instanceof LongConstantOperand)) {
if (!canBeImmediate(((LongConstantOperand) addr).value, signed)) {
RegisterOperand rop = ir.regpool.makeTempLong();
s.insertBefore(Move.create(REF_MOVE, rop, addr));
return rop.copyD2U();
} else {
// can be immediate --> convert to int
return new IntConstantOperand((int) ((LongConstantOperand) addr).value);
}
} else if (addr instanceof ConstantOperand) {
// must not happen
if (VM.VerifyAssertions)
VM._assert(VM.NOT_REACHED);
}
// Operand was OK as is.
return addr;
}
use of org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand in project JikesRVM by JikesRVM.
the class NormalizeConstants method asRegLong.
static Operand asRegLong(Operand addr, Instruction s, IR ir) {
if (VM.BuildFor64Addr && (addr instanceof LongConstantOperand)) {
RegisterOperand rop = ir.regpool.makeTempLong();
s.insertBefore(Move.create(REF_MOVE, rop, addr));
return rop.copyD2U();
} else if (addr instanceof ConstantOperand) {
// must not happen
if (VM.VerifyAssertions)
VM._assert(VM.NOT_REACHED);
}
// Operand was OK as is.
return addr;
}
use of org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand in project JikesRVM by JikesRVM.
the class NormalizeConstants method asImmediateOrRegPolymorphic.
static Operand asImmediateOrRegPolymorphic(Operand addr, Instruction s, IR ir, boolean signed) {
if (addr instanceof IntConstantOperand) {
if (!canBeImmediate(((IntConstantOperand) addr).value, signed)) {
RegisterOperand rop = ir.regpool.makeTempInt();
s.insertBefore(Move.create(REF_MOVE, rop, addr));
return rop.copyD2U();
}
} else if (addr instanceof AddressConstantOperand) {
if (!canBeImmediate(((AddressConstantOperand) addr).value, signed)) {
RegisterOperand rop = ir.regpool.makeTempAddress();
s.insertBefore(Move.create(REF_MOVE, rop, addr));
return rop.copyD2U();
} else {
// can be immediate --> convert to int
return new IntConstantOperand(((AddressConstantOperand) addr).value.toInt());
}
} else if (VM.BuildFor64Addr && (addr instanceof LongConstantOperand)) {
if (!canBeImmediate(((LongConstantOperand) addr).value, signed)) {
RegisterOperand rop = ir.regpool.makeTempLong();
s.insertBefore(Move.create(REF_MOVE, rop, addr));
return rop.copyD2U();
} else {
// can be immediate --> convert to int
return new IntConstantOperand((int) ((LongConstantOperand) addr).value);
}
}
// Operand was OK as is.
return addr;
}
use of org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand in project JikesRVM by JikesRVM.
the class BURS_Helpers method BOOLEAN_CMP_LONG.
/**
* Expansion of BOOLEAN_CMP_LONG
*
* @param s the instruction to copy position info from
* @param res the result operand
* @param val1 the first value
* @param val2 the second value
* @param cond the condition operand
*/
protected final void BOOLEAN_CMP_LONG(Instruction s, RegisterOperand res, Operand val1, Operand val2, ConditionOperand cond) {
// Can we simplify to a shift?
if (cond.isLESS() && val2.isLongConstant() && val2.asLongConstant().value == 0 && val1.isRegister()) {
// Put the most significant bit of val1 into res
Register val1_reg = val1.asRegister().getRegister();
EMIT(MIR_Move.create(IA32_MOV, res.copyRO(), new RegisterOperand(val1_reg, TypeReference.Int)));
EMIT(MIR_BinaryAcc.mutate(s, IA32_SHR, res, IC(31)));
} else if (cond.isGREATER_EQUAL() && val2.isLongConstant() && val2.asLongConstant().value == 0 && val1.isRegister()) {
// Put the most significant bit of val1 into res and invert
Register val1_reg = val1.asRegister().getRegister();
EMIT(MIR_Move.create(IA32_MOV, res.copyRO(), new RegisterOperand(val1_reg, TypeReference.Int)));
EMIT(MIR_BinaryAcc.mutate(s, IA32_SHR, res, IC(31)));
EMIT(MIR_BinaryAcc.create(IA32_XOR, res.copyRO(), IC(1)));
} else {
// ==/!= : do subtract then OR 2 32-bit quantities test for zero/non-zero
if (cond.isGREATER() || cond.isLESS_EQUAL()) {
Operand swap_temp;
cond.flipOperands();
swap_temp = val1;
val1 = val2;
val2 = swap_temp;
}
if (VM.VerifyAssertions) {
opt_assert(cond.isEQUAL() || cond.isNOT_EQUAL() || cond.isLESS() || cond.isGREATER_EQUAL());
}
RegisterOperand one = regpool.makeTempInt();
RegisterOperand lone = regpool.makeTempInt();
Operand two, ltwo;
if (val1 instanceof RegisterOperand) {
Register val1_reg = val1.asRegister().getRegister();
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, one, new RegisterOperand(val1_reg, TypeReference.Int))));
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, lone, new RegisterOperand(regpool.getSecondReg(val1_reg), TypeReference.Int))));
} else {
LongConstantOperand tmp = (LongConstantOperand) val1;
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, one, IC(tmp.upper32()))));
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, lone, IC(tmp.lower32()))));
}
if (val2 instanceof RegisterOperand) {
two = val2;
((RegisterOperand) two).setType(TypeReference.Int);
ltwo = new RegisterOperand(burs.ir.regpool.getSecondReg(val2.asRegister().getRegister()), TypeReference.Int);
} else {
LongConstantOperand tmp = (LongConstantOperand) val2;
two = IC(tmp.upper32());
ltwo = IC(tmp.lower32());
}
if (cond.isEQUAL() || cond.isNOT_EQUAL()) {
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SUB, lone.copyRO(), ltwo)));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SBB, one.copyRO(), two)));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_OR, one.copyRO(), lone.copyRO())));
} else {
EMIT(CPOS(s, MIR_Compare.create(IA32_CMP, lone.copyRO(), ltwo)));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SBB, one.copyRO(), two)));
}
RegisterOperand temp = regpool.makeTemp(TypeReference.Boolean);
EMIT(CPOS(s, MIR_Set.create(IA32_SET__B, temp, COND(cond))));
EMIT(MIR_Unary.mutate(s, IA32_MOVZX__B, res, temp.copyRO()));
}
}
use of org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand in project JikesRVM by JikesRVM.
the class BURS_Helpers method LONG_MUL.
/**
* Expansion of LONG_MUL
*
* @param s the instruction to expand
* @param result the result operand
* @param value1 the first operand
* @param value2 the second operand
*/
protected final void LONG_MUL(Instruction s, RegisterOperand result, Operand value1, Operand value2) {
if (value2.isRegister()) {
// a branch
if (VM.VerifyAssertions)
opt_assert(Binary.getResult(s).similar(result) && Binary.getVal1(s).similar(value1) && Binary.getVal2(s).similar(value2));
EMIT(s);
} else {
// register in the case of multiplication with a constant
if ((value2.similar(result)) || value1.isLongConstant()) {
Operand temp = value1;
value1 = value2;
value2 = temp;
}
if (VM.VerifyAssertions)
opt_assert(value1.isRegister() && value2.isLongConstant());
// In general, (a,b) * (c,d) = (l(a imul d)+l(b imul c)+u(b mul d), l(b mul d))
Register lhsReg = result.getRegister();
Register lowlhsReg = regpool.getSecondReg(lhsReg);
LongConstantOperand rhs2 = (LongConstantOperand) value2;
// a
Register rhsReg1 = value1.asRegister().getRegister();
// b
Register lowrhsReg1 = regpool.getSecondReg(rhsReg1);
// c
int high2 = rhs2.upper32();
// d
int low2 = rhs2.lower32();
// (where * is something other than -1,0,1)
if (high2 == -1) {
if (low2 == 0) {
// CLAIM: (a,b) * (-1,0) = (-b,0)
if (VM.VerifyAssertions)
opt_assert(lhsReg != lowrhsReg1);
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
EMIT(CPOS(s, MIR_UnaryAcc.create(IA32_NEG, new RegisterOperand(lhsReg, TypeReference.Int))));
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), IC(0))));
} else if (low2 == 1) {
// CLAIM: (a,b) * (-1,1) = (a-b,b)
if (lowlhsReg != lowrhsReg1) {
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
}
if (lhsReg != rhsReg1) {
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
}
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SUB, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(lowlhsReg, TypeReference.Int))));
} else {
// CLAIM: (a,b) * (-1, d) = (l(a imul d)-b+u(b mul d), l(b mul d))
if (lhsReg != rhsReg1) {
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
}
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_IMUL2, new RegisterOperand(lhsReg, TypeReference.Int), IC(low2))));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SUB, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(getEAX(), TypeReference.Int), IC(low2))));
EMIT(CPOS(s, MIR_Multiply.create(IA32_MUL, new RegisterOperand(getEDX(), TypeReference.Int), new RegisterOperand(getEAX(), TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(getEAX(), TypeReference.Int))));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_ADD, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(getEDX(), TypeReference.Int))));
}
} else if (high2 == 0) {
if (low2 == -1) {
// 0, -1
// CLAIM: (a,b) * (0,-1) = (b-(a+(b!=0?1:0)),-b)
// avoid clobbering a and b by using tmp
Register tmp = regpool.getInteger();
if (lowlhsReg != lowrhsReg1) {
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
}
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(tmp, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
EMIT(CPOS(s, MIR_UnaryAcc.create(IA32_NEG, new RegisterOperand(lowlhsReg, TypeReference.Int))));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SBB, new RegisterOperand(tmp, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(tmp, TypeReference.Int))));
} else {
// CLAIM: (a,b) * (0,d) = (l(a imul d)+u(b mul d), l(b mul d))
if (lhsReg != rhsReg1) {
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
}
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_IMUL2, new RegisterOperand(lhsReg, TypeReference.Int), IC(low2))));
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(getEAX(), TypeReference.Int), IC(low2))));
EMIT(CPOS(s, MIR_Multiply.create(IA32_MUL, new RegisterOperand(getEDX(), TypeReference.Int), new RegisterOperand(getEAX(), TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(getEAX(), TypeReference.Int))));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_ADD, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(getEDX(), TypeReference.Int))));
}
} else if (high2 == 1) {
if (low2 == -1) {
// 1, -1
// CLAIM: (a,b) * (1,-1) = (2b-(a+(b!=0?1:0)),-b)
// avoid clobbering a and b by using tmp
Register tmp = regpool.getInteger();
if (lowlhsReg != lowrhsReg1) {
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
}
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(tmp, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_ADD, new RegisterOperand(tmp, TypeReference.Int), new RegisterOperand(tmp, TypeReference.Int))));
EMIT(CPOS(s, MIR_UnaryAcc.create(IA32_NEG, new RegisterOperand(lowlhsReg, TypeReference.Int))));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SBB, new RegisterOperand(tmp, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(tmp, TypeReference.Int))));
} else if (low2 == 0) {
// 1, 0
// CLAIM: (x,y) * (1,0) = (y,0)
// NB we should have simplified this LONG_MUL to a LONG_SHIFT
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), IC(0))));
} else if (low2 == 1) {
// NB we should have simplified this LONG_MUL to a LONG_SHIFT and LONG_ADDs
if (lowlhsReg != lowrhsReg1) {
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
}
if (lhsReg != rhsReg1) {
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
}
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_ADD, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(lowlhsReg, TypeReference.Int))));
} else {
// CLAIM: (a,b) * (1,d) = (l(a imul d)+b+u(b mul d), l(b mul d))
if (lhsReg != rhsReg1) {
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
}
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_IMUL2, new RegisterOperand(lhsReg, TypeReference.Int), IC(low2))));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_ADD, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(getEAX(), TypeReference.Int), IC(low2))));
EMIT(CPOS(s, MIR_Multiply.create(IA32_MUL, new RegisterOperand(getEDX(), TypeReference.Int), new RegisterOperand(getEAX(), TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(getEAX(), TypeReference.Int))));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_ADD, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(getEDX(), TypeReference.Int))));
}
} else {
if (low2 == -1) {
// *, -1
// CLAIM: (a,b) * (c, -1) = ((b+1)*c - (a + b==0?1:0), -b)
// avoid clobbering a and b by using tmp
Register tmp = regpool.getInteger();
if (lowlhsReg != lowrhsReg1) {
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
}
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(tmp, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_ADD, new RegisterOperand(tmp, TypeReference.Int), IC(1))));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_IMUL2, new RegisterOperand(tmp, TypeReference.Int), IC(high2))));
EMIT(CPOS(s, MIR_UnaryAcc.create(IA32_NEG, new RegisterOperand(lowlhsReg, TypeReference.Int))));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SBB, new RegisterOperand(tmp, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(tmp, TypeReference.Int))));
} else if (low2 == 0) {
// *, 0
// CLAIM: (a,b) * (c,0) = (l(b imul c),0)
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_IMUL2, new RegisterOperand(lhsReg, TypeReference.Int), IC(high2))));
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), IC(0))));
} else if (low2 == 1) {
// CLAIM: (x,y) * (z,1) = (l(y imul z)+x,y)
if (lowlhsReg != lowrhsReg1) {
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
}
if (lhsReg != rhsReg1) {
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
}
Register tmp = regpool.getInteger();
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(tmp, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_IMUL2, new RegisterOperand(tmp, TypeReference.Int), IC(high2))));
EMIT(CPOS(s, MIR_Move.create(IA32_ADD, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(tmp, TypeReference.Int))));
} else {
// (a,b) * (c,d) = (l(a imul d)+l(b imul c)+u(b mul d), l(b mul d))
if (lhsReg != rhsReg1) {
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(rhsReg1, TypeReference.Int))));
}
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_IMUL2, new RegisterOperand(lhsReg, TypeReference.Int), IC(low2))));
Register tmp = regpool.getInteger();
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(tmp, TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_IMUL2, new RegisterOperand(tmp, TypeReference.Int), IC(high2))));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_ADD, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(tmp, TypeReference.Int))));
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(getEAX(), TypeReference.Int), IC(low2))));
EMIT(CPOS(s, MIR_Multiply.create(IA32_MUL, new RegisterOperand(getEDX(), TypeReference.Int), new RegisterOperand(getEAX(), TypeReference.Int), new RegisterOperand(lowrhsReg1, TypeReference.Int))));
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(lowlhsReg, TypeReference.Int), new RegisterOperand(getEAX(), TypeReference.Int))));
EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_ADD, new RegisterOperand(lhsReg, TypeReference.Int), new RegisterOperand(getEDX(), TypeReference.Int))));
}
}
}
}
Aggregations