use of org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand in project JikesRVM by JikesRVM.
the class BURS_Helpers method OSR.
/**
* special case handling OSR instructions expand long type variables to two
* integers
* @param burs the burs instance
* @param s an OSRPoint instruction
*/
protected void OSR(BURS burs, Instruction s) {
if (VM.VerifyAssertions) {
opt_assert(OsrPoint.conforms(s));
}
// Check type info first because this needs to be done
// for both 32-bit and 64-bit cases.
InlinedOsrTypeInfoOperand typeInfo;
if (VM.BuildFor32Addr) {
// Clearing type info is ok, because instruction will be mutated and the
// info will be reinserted
typeInfo = OsrPoint.getClearInlinedTypeInfo(s);
} else {
// Instruction won't be changed so info needs to be left in
typeInfo = OsrPoint.getInlinedTypeInfo(s);
}
if (VM.VerifyAssertions) {
if (typeInfo == null) {
VM.sysWriteln("OsrPoint " + s + " has a <null> type info:");
VM.sysWriteln(" position :" + s.getBytecodeIndex() + "@" + s.position().method);
}
opt_assert(typeInfo != null);
}
int numparam = OsrPoint.getNumberOfElements(s);
if (VM.BuildFor32Addr) {
// 1. how many params
int numlong = 0;
for (int i = 0; i < numparam; i++) {
Operand param = OsrPoint.getElement(s, i);
if (param.getType().isLongType()) {
numlong++;
}
}
// 2. collect params
Operand[] params = new Operand[numparam];
for (int i = 0; i < numparam; i++) {
params[i] = OsrPoint.getClearElement(s, i);
}
// set the number of valid params in osr type info, used
// in LinearScan
typeInfo.validOps = numparam;
// 3: only makes second half register of long being used
// creates room for long types.
burs.append(OsrPoint.mutate(s, s.operator(), typeInfo, numparam + numlong));
int pidx = numparam;
for (int i = 0; i < numparam; i++) {
Operand param = params[i];
OsrPoint.setElement(s, i, param);
if (param instanceof RegisterOperand) {
RegisterOperand rparam = (RegisterOperand) param;
// LinearScan will update the map.
if (rparam.getType().isLongType()) {
OsrPoint.setElement(s, pidx++, L(burs.ir.regpool.getSecondReg(rparam.getRegister())));
}
} else if (param instanceof LongConstantOperand) {
LongConstantOperand val = (LongConstantOperand) param;
if (VM.TraceOnStackReplacement) {
VM.sysWriteln("caught a long const " + val);
}
OsrPoint.setElement(s, i, IC(val.upper32()));
OsrPoint.setElement(s, pidx++, IC(val.lower32()));
} else if (param instanceof IntConstantOperand) {
} else {
throw new OptimizingCompilerException("BURS_Helpers", "unexpected parameter type" + param);
}
}
if (pidx != (numparam + numlong)) {
VM.sysWriteln("pidx = " + pidx);
VM.sysWriteln("numparam = " + numparam);
VM.sysWriteln("numlong = " + numlong);
}
if (VM.VerifyAssertions) {
opt_assert(pidx == (numparam + numlong));
}
} else {
// set the number of valid params in osr type info, used
// in LinearScan
typeInfo.validOps = numparam;
burs.append(s);
}
}
use of org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand in project JikesRVM by JikesRVM.
the class BURS_Helpers method GPR2FPR_64.
/**
* Emits code to move 64 bits from GPRs to FPRs.
*
* @param s instruction to modify for the move
*/
protected final void GPR2FPR_64(Instruction s) {
int offset = -burs.ir.stackManager.allocateSpaceForConversion();
StackLocationOperand sl = new StackLocationOperand(true, offset, QW);
StackLocationOperand sl1 = new StackLocationOperand(true, offset + 4, DW);
StackLocationOperand sl2 = new StackLocationOperand(true, offset, DW);
Operand i1, i2;
Operand val = Unary.getClearVal(s);
if (val instanceof RegisterOperand) {
RegisterOperand rval = (RegisterOperand) val;
i1 = val;
i2 = new RegisterOperand(regpool.getSecondReg(rval.getRegister()), TypeReference.Int);
} else {
LongConstantOperand rhs = (LongConstantOperand) val;
i1 = IC(rhs.upper32());
i2 = IC(rhs.lower32());
}
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, sl1, i1)));
EMIT(CPOS(s, MIR_Move.create(IA32_MOV, sl2, i2)));
EMIT(MIR_Move.mutate(s, IA32_FMOV, Unary.getResult(s), sl));
}
use of org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand in project JikesRVM by JikesRVM.
the class NormalBURS method buildTrees.
/**
* Stage 1: Complete the expression trees and identify tree roots.
* Complete BURS trees by adding leaf nodes as needed, and
* creating tree edges by calling insertChild1() or insertChild2()
* This step is also where we introduce intermediate tree nodes for
* any LIR instruction that has > 2 "real" operands e.g., a CALL.
* We also mark nodes that must be tree roots.
*
* @param dg The dependence graph.
*/
private void buildTrees(DepGraph dg) {
DepGraphNode bbNodes = (DepGraphNode) dg.firstNode();
for (DepGraphNode n = bbNodes; n != null; n = (DepGraphNode) n.getNext()) {
// Initialize n.treeNode
AbstractBURS_TreeNode cur_parent = AbstractBURS_TreeNode.create(n);
castNode(n).setCurrentParent(cur_parent);
Instruction instr = n.instruction();
// loop for USES of an instruction
for (Enumeration<Operand> uses = instr.getUses(); uses.hasMoreElements(); ) {
// Create tree edge for next use.
Operand op = uses.nextElement();
if (op == null)
continue;
// Set child = AbstractBURS_TreeNode for operand op
AbstractBURS_TreeNode child;
if (op instanceof RegisterOperand) {
RegisterOperand regOp = (RegisterOperand) op;
// ignore validation registers
if (regOp.getRegister().isValidation())
continue;
DepGraphEdge e = DepGraphEdge.findInputEdge(n, op);
if (e == null) {
// operand is leaf
child = Register;
} else {
child = castNode(e.fromNode()).getCurrentParent();
}
} else if (op instanceof IntConstantOperand) {
child = new BURS_IntConstantTreeNode(((IntConstantOperand) op).value);
} else if (op instanceof LongConstantOperand) {
child = LongConstant;
} else if (op instanceof AddressConstantOperand) {
child = AddressConstant;
} else if (op instanceof BranchOperand && instr.isCall()) {
child = BranchTarget;
} else if (op instanceof InlinedOsrTypeInfoOperand && instr.isYieldPoint()) {
child = NullTreeNode;
} else {
continue;
}
// Attach child as child of cur_parent in correct position
if (cur_parent.getChild1() == null) {
cur_parent.setChild1(child);
} else if (cur_parent.getChild2() == null) {
cur_parent.setChild2(child);
} else {
// Create auxiliary node so as to represent
// a instruction with arity > 2 in a binary tree.
AbstractBURS_TreeNode child1 = cur_parent.getChild2();
AbstractBURS_TreeNode aux = AbstractBURS_TreeNode.create(OTHER_OPERAND_opcode);
cur_parent.setChild2(aux);
cur_parent = aux;
cur_parent.setChild1(child1);
cur_parent.setChild2(child);
}
}
// patch for calls & return
switch(instr.getOpcode()) {
case CALL_opcode:
case SYSCALL_opcode:
case YIELDPOINT_OSR_opcode:
if (cur_parent.getChild2() == null) {
cur_parent.setChild2(NullTreeNode);
}
// fall through
case RETURN_opcode:
if (cur_parent.getChild1() == null) {
cur_parent.setChild1(NullTreeNode);
}
}
if (mustBeTreeRoot(n)) {
makeTreeRoot(castNode(n).getCurrentParent());
}
}
}
use of org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand in project JikesRVM by JikesRVM.
the class BURS_Helpers method CALL.
/**
* Expansion of CALL. 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 CALL(Instruction s, Operand address) {
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;
if (result != null && result.getType().isLongType()) {
result.setType(TypeReference.Int);
result2 = 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_CALL, result, result2, address, Call.getMethod(s), numParams + longParams);
for (int paramIdx = 0, mirCallIdx = 0; paramIdx < numParams; ) {
Operand param = params[paramIdx++];
if (param instanceof RegisterOperand) {
RegisterOperand rparam = (RegisterOperand) param;
MIR_Call.setParam(s, mirCallIdx++, rparam);
if (rparam.getType().isLongType()) {
rparam.setType(TypeReference.Int);
MIR_Call.setParam(s, mirCallIdx - 1, rparam);
MIR_Call.setParam(s, mirCallIdx++, new RegisterOperand(regpool.getSecondReg(rparam.getRegister()), TypeReference.Int));
}
} else if (param instanceof LongConstantOperand) {
LongConstantOperand val = (LongConstantOperand) param;
MIR_Call.setParam(s, mirCallIdx++, IC(val.upper32()));
MIR_Call.setParam(s, mirCallIdx++, IC(val.lower32()));
} else {
MIR_Call.setParam(s, mirCallIdx++, param);
}
}
} else {
MIR_Call.mutate(s, IA32_CALL, 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_Helpers method LCMP_CMOV.
/**
* Generate a long compare and cmov
*
* @param s the instruction to copy position info from
* @param result the result of the conditional move
* @param val1 the first value
* @param val2 the second value
* @param cond the condition operand
* @param trueValue the value to move to result if cond is true
* @param falseValue the value to move to result if cond is not true
*/
protected final void LCMP_CMOV(Instruction s, RegisterOperand result, Operand val1, Operand val2, ConditionOperand cond, Operand trueValue, Operand falseValue) {
// ==/!= : 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)));
}
CMOV_MOV(s, result, cond, trueValue, falseValue);
}
Aggregations