use of com.oracle.truffle.llvm.runtime.nodes.asm.support.LLVMAMD64WriteTupelNode in project graal by oracle.
the class AsmFactory method createBinaryOperation.
void createBinaryOperation(String operation, AsmOperand a, AsmOperand b) {
LLVMExpressionNode srcA;
LLVMExpressionNode srcB;
LLVMExpressionNode out;
assert a != null && b != null;
AsmOperand dst = b;
Type dstType;
char suffix = operation.charAt(operation.length() - 1);
dstType = getPrimitiveTypeFromSuffix(suffix);
srcB = getOperandLoad(dstType, b);
if (isShiftOperation(operation)) {
srcA = getOperandLoad(PrimitiveType.I8, a);
} else {
srcA = getOperandLoad(dstType, a);
}
switch(operation) {
case "addb":
out = LLVMAMD64AddbNodeGen.create(getUpdateCPZSOFlagsNode(), srcA, srcB);
break;
case "addw":
out = LLVMAMD64AddwNodeGen.create(getUpdateCPZSOFlagsNode(), srcA, srcB);
break;
case "addl":
out = LLVMAMD64AddlNodeGen.create(getUpdateCPZSOFlagsNode(), srcA, srcB);
break;
case "addq":
out = LLVMAMD64AddqNodeGen.create(getUpdateCPZSOFlagsNode(), srcA, srcB);
break;
case "adcb":
out = LLVMAMD64AdcbNodeGen.create(getUpdateCPZSOFlagsNode(), srcA, srcB, getFlag(LLVMAMD64Flags.CF));
break;
case "adcw":
out = LLVMAMD64AdcwNodeGen.create(getUpdateCPZSOFlagsNode(), srcA, srcB, getFlag(LLVMAMD64Flags.CF));
break;
case "adcl":
out = LLVMAMD64AdclNodeGen.create(getUpdateCPZSOFlagsNode(), srcA, srcB, getFlag(LLVMAMD64Flags.CF));
break;
case "adcq":
out = LLVMAMD64AdcqNodeGen.create(getUpdateCPZSOFlagsNode(), srcA, srcB, getFlag(LLVMAMD64Flags.CF));
break;
case "subb":
out = LLVMAMD64SubbNodeGen.create(srcB, srcA);
break;
case "subw":
out = LLVMAMD64SubwNodeGen.create(srcB, srcA);
break;
case "subl":
out = LLVMAMD64SublNodeGen.create(srcB, srcA);
break;
case "subq":
out = LLVMAMD64SubqNodeGen.create(srcB, srcA);
break;
case "idivb":
srcA = getOperandLoad(PrimitiveType.I8, a);
srcB = getOperandLoad(PrimitiveType.I16, b);
out = LLVMAMD64IdivbNodeGen.create(srcB, srcA);
dst = new AsmRegisterOperand("ax");
dstType = PrimitiveType.I16;
break;
case "idivw":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("ax"), getRegisterStore("dx"));
LLVMExpressionNode high = getOperandLoad(PrimitiveType.I16, new AsmRegisterOperand("dx"));
statements.add(LLVMAMD64IdivwNodeGen.create(res, high, srcB, srcA));
return;
}
case "idivl":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("eax"), getRegisterStore("edx"));
LLVMExpressionNode high = getOperandLoad(PrimitiveType.I32, new AsmRegisterOperand("edx"));
statements.add(LLVMAMD64IdivlNodeGen.create(res, high, srcB, srcA));
return;
}
case "idivq":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("rax"), getRegisterStore("rdx"));
LLVMExpressionNode high = getOperandLoad(PrimitiveType.I32, new AsmRegisterOperand("rdx"));
statements.add(LLVMAMD64IdivqNodeGen.create(res, high, srcB, srcA));
return;
}
case "imulw":
{
LLVMAMD64WriteValueNode res = getRegisterStore(dstType, dst);
statements.add(LLVMAMD64Imulw3NodeGen.create(getFlagWrite(LLVMAMD64Flags.CF), getFlagWrite(LLVMAMD64Flags.PF), getFlagWrite(LLVMAMD64Flags.AF), getFlagWrite(LLVMAMD64Flags.ZF), getFlagWrite(LLVMAMD64Flags.SF), getFlagWrite(LLVMAMD64Flags.OF), res, srcA, srcB));
return;
}
case "imull":
{
LLVMAMD64WriteValueNode res = getRegisterStore(dstType, dst);
statements.add(LLVMAMD64Imull3NodeGen.create(getFlagWrite(LLVMAMD64Flags.CF), getFlagWrite(LLVMAMD64Flags.PF), getFlagWrite(LLVMAMD64Flags.AF), getFlagWrite(LLVMAMD64Flags.ZF), getFlagWrite(LLVMAMD64Flags.SF), getFlagWrite(LLVMAMD64Flags.OF), res, srcA, srcB));
return;
}
case "imulq":
{
LLVMAMD64WriteValueNode res = getRegisterStore(dstType, dst);
statements.add(LLVMAMD64Imulq3NodeGen.create(getFlagWrite(LLVMAMD64Flags.CF), getFlagWrite(LLVMAMD64Flags.PF), getFlagWrite(LLVMAMD64Flags.AF), getFlagWrite(LLVMAMD64Flags.ZF), getFlagWrite(LLVMAMD64Flags.SF), getFlagWrite(LLVMAMD64Flags.OF), res, srcA, srcB));
return;
}
case "movb":
case "movw":
case "movl":
case "movq":
out = srcA;
break;
case "movsbw":
srcA = getOperandLoad(PrimitiveType.I8, a);
out = CommonNodeFactory.createSignedCast(srcA, PrimitiveType.I16);
break;
case "movsbl":
srcA = getOperandLoad(PrimitiveType.I8, a);
out = CommonNodeFactory.createSignedCast(srcA, PrimitiveType.I32);
break;
case "movsbq":
srcA = getOperandLoad(PrimitiveType.I8, a);
out = CommonNodeFactory.createSignedCast(srcA, PrimitiveType.I64);
break;
case "movswl":
srcA = getOperandLoad(PrimitiveType.I16, a);
out = CommonNodeFactory.createSignedCast(srcA, PrimitiveType.I32);
break;
case "movswq":
srcA = getOperandLoad(PrimitiveType.I16, a);
out = CommonNodeFactory.createSignedCast(srcA, PrimitiveType.I64);
break;
case "movslq":
srcA = getOperandLoad(PrimitiveType.I32, a);
out = CommonNodeFactory.createSignedCast(srcA, PrimitiveType.I64);
break;
case "movzbw":
srcA = getOperandLoad(PrimitiveType.I8, a);
out = CommonNodeFactory.createUnsignedCast(srcA, PrimitiveType.I16);
break;
case "movzbl":
srcA = getOperandLoad(PrimitiveType.I8, a);
out = CommonNodeFactory.createUnsignedCast(srcA, PrimitiveType.I32);
break;
case "movzbq":
srcA = getOperandLoad(PrimitiveType.I8, a);
out = CommonNodeFactory.createUnsignedCast(srcA, PrimitiveType.I64);
break;
case "movzwl":
srcA = getOperandLoad(PrimitiveType.I16, a);
out = CommonNodeFactory.createUnsignedCast(srcA, PrimitiveType.I32);
break;
case "movzwq":
srcA = getOperandLoad(PrimitiveType.I16, a);
out = CommonNodeFactory.createUnsignedCast(srcA, PrimitiveType.I64);
break;
case "salb":
out = LLVMAMD64SalbNodeGen.create(srcB, srcA);
break;
case "salw":
out = LLVMAMD64SalwNodeGen.create(srcB, srcA);
break;
case "sall":
out = LLVMAMD64SallNodeGen.create(srcB, srcA);
break;
case "salq":
out = LLVMAMD64SalqNodeGen.create(srcB, srcA);
break;
case "sarb":
out = LLVMAMD64SarbNodeGen.create(srcB, srcA);
break;
case "sarw":
out = LLVMAMD64SarwNodeGen.create(srcB, srcA);
break;
case "sarl":
out = LLVMAMD64SarlNodeGen.create(srcB, srcA);
break;
case "sarq":
out = LLVMAMD64SarqNodeGen.create(srcB, srcA);
break;
case "shlb":
out = LLVMAMD64ShlbNodeGen.create(srcB, srcA);
break;
case "shlw":
out = LLVMAMD64ShlwNodeGen.create(srcB, srcA);
break;
case "shll":
out = LLVMAMD64ShllNodeGen.create(srcB, srcA);
break;
case "shlq":
out = LLVMAMD64ShlqNodeGen.create(srcB, srcA);
break;
case "shrb":
out = LLVMAMD64ShrbNodeGen.create(srcB, srcA);
break;
case "shrw":
out = LLVMAMD64ShrwNodeGen.create(srcB, srcA);
break;
case "shrl":
out = LLVMAMD64ShrlNodeGen.create(srcB, srcA);
break;
case "shrq":
out = LLVMAMD64ShrqNodeGen.create(srcB, srcA);
break;
case "rolb":
out = LLVMAMD64RolbNodeGen.create(srcB, srcA);
break;
case "rolw":
out = LLVMAMD64RolwNodeGen.create(srcB, srcA);
break;
case "roll":
out = LLVMAMD64RollNodeGen.create(srcB, srcA);
break;
case "rolq":
out = LLVMAMD64RolqNodeGen.create(srcB, srcA);
break;
case "rorb":
out = LLVMAMD64RorbNodeGen.create(srcB, srcA);
break;
case "rorw":
out = LLVMAMD64RorwNodeGen.create(srcB, srcA);
break;
case "rorl":
out = LLVMAMD64RorlNodeGen.create(srcB, srcA);
break;
case "rorq":
out = LLVMAMD64RorqNodeGen.create(srcB, srcA);
break;
case "andb":
out = LLVMAMD64AndbNodeGen.create(getUpdatePZSFlagsNode(), srcA, srcB);
break;
case "andw":
out = LLVMAMD64AndwNodeGen.create(getUpdatePZSFlagsNode(), srcA, srcB);
break;
case "andl":
out = LLVMAMD64AndlNodeGen.create(getUpdatePZSFlagsNode(), srcA, srcB);
break;
case "andq":
out = LLVMAMD64AndqNodeGen.create(getUpdatePZSFlagsNode(), srcA, srcB);
break;
case "orb":
out = LLVMAMD64OrbNodeGen.create(srcA, srcB);
break;
case "orw":
out = LLVMAMD64OrwNodeGen.create(srcA, srcB);
break;
case "orl":
out = LLVMAMD64OrlNodeGen.create(srcA, srcB);
break;
case "orq":
out = LLVMAMD64OrqNodeGen.create(srcA, srcB);
break;
case "xchgb":
{
XchgOperands operands = new XchgOperands(a, b, dstType);
statements.add(makeAtomic(LLVMAMD64XchgbNodeGen.create(operands.dst, operands.srcA, operands.srcB), b));
return;
}
case "xchgw":
{
XchgOperands operands = new XchgOperands(a, b, dstType);
statements.add(makeAtomic(LLVMAMD64XchgwNodeGen.create(operands.dst, operands.srcA, operands.srcB), b));
return;
}
case "xchgl":
{
XchgOperands operands = new XchgOperands(a, b, dstType);
statements.add(makeAtomic(LLVMAMD64XchglNodeGen.create(operands.dst, operands.srcA, operands.srcB), b));
return;
}
case "xchgq":
{
XchgOperands operands = new XchgOperands(a, b, dstType);
statements.add(makeAtomic(LLVMAMD64XchgqNodeGen.create(operands.dst, operands.srcA, operands.srcB), b));
return;
}
case "cmpb":
statements.add(LLVMAMD64CmpbNodeGen.create(getUpdateCPAZSOFlagsNode(), srcB, srcA));
return;
case "cmpw":
statements.add(LLVMAMD64CmpwNodeGen.create(getUpdateCPAZSOFlagsNode(), srcB, srcA));
return;
case "cmpl":
statements.add(LLVMAMD64CmplNodeGen.create(getUpdateCPAZSOFlagsNode(), srcB, srcA));
return;
case "cmpq":
statements.add(LLVMAMD64CmpqNodeGen.create(getUpdateCPAZSOFlagsNode(), srcB, srcA));
return;
case "cmpxchgb":
{
LLVMAMD64WriteValueNode dst1 = getStore(dstType, b);
LLVMAMD64WriteValueNode dst2 = getRegisterStore("al");
LLVMExpressionNode accumulator = getOperandLoad(PrimitiveType.I8, new AsmRegisterOperand("al"));
statements.add(maybeMakeAtomic(LLVMAMD64CmpXchgbNodeGen.create(getUpdateCPAZSOFlagsNode(), dst1, dst2, accumulator, srcA, srcB), b));
return;
}
case "cmpxchgw":
{
LLVMAMD64WriteValueNode dst1 = getStore(dstType, b);
LLVMAMD64WriteValueNode dst2 = getRegisterStore("ax");
LLVMExpressionNode accumulator = getOperandLoad(PrimitiveType.I16, new AsmRegisterOperand("ax"));
statements.add(maybeMakeAtomic(LLVMAMD64CmpXchgwNodeGen.create(getUpdateCPAZSOFlagsNode(), dst1, dst2, accumulator, srcA, srcB), b));
return;
}
case "cmpxchgl":
{
LLVMAMD64WriteValueNode dst1 = getStore(dstType, b);
LLVMAMD64WriteValueNode dst2 = getRegisterStore("eax");
LLVMExpressionNode accumulator = getOperandLoad(PrimitiveType.I32, new AsmRegisterOperand("eax"));
statements.add(maybeMakeAtomic(LLVMAMD64CmpXchglNodeGen.create(getUpdateCPAZSOFlagsNode(), dst1, dst2, accumulator, srcA, srcB), b));
return;
}
case "cmpxchgq":
{
LLVMAMD64WriteValueNode dst1 = getStore(dstType, b);
LLVMAMD64WriteValueNode dst2 = getRegisterStore("rax");
LLVMExpressionNode accumulator = getOperandLoad(PrimitiveType.I64, new AsmRegisterOperand("rax"));
statements.add(maybeMakeAtomic(LLVMAMD64CmpXchgqNodeGen.create(getUpdateCPAZSOFlagsNode(), dst1, dst2, accumulator, srcA, srcB), b));
return;
}
case "xaddb":
{
LLVMAMD64WriteValueNode dst1 = getRegisterStore(PrimitiveType.I8, a);
LLVMAMD64WriteValueNode dst2 = getStore(dstType, dst);
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(dst1, dst2);
statements.add(maybeMakeAtomic(LLVMAMD64XaddbNodeGen.create(getUpdateCPZSOFlagsNode(), res, srcA, srcB), b));
return;
}
case "xaddw":
{
LLVMAMD64WriteValueNode dst1 = getRegisterStore(PrimitiveType.I16, a);
LLVMAMD64WriteValueNode dst2 = getStore(dstType, dst);
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(dst1, dst2);
statements.add(maybeMakeAtomic(LLVMAMD64XaddwNodeGen.create(getUpdateCPZSOFlagsNode(), res, srcA, srcB), b));
return;
}
case "xaddl":
{
LLVMAMD64WriteValueNode dst1 = getRegisterStore(PrimitiveType.I32, a);
LLVMAMD64WriteValueNode dst2 = getStore(dstType, dst);
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(dst1, dst2);
statements.add(maybeMakeAtomic(LLVMAMD64XaddlNodeGen.create(getUpdateCPZSOFlagsNode(), res, srcA, srcB), b));
return;
}
case "xaddq":
{
LLVMAMD64WriteValueNode dst1 = getRegisterStore(PrimitiveType.I64, a);
LLVMAMD64WriteValueNode dst2 = getStore(dstType, dst);
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(dst1, dst2);
statements.add(maybeMakeAtomic(LLVMAMD64XaddqNodeGen.create(getUpdateCPZSOFlagsNode(), res, srcA, srcB), b));
return;
}
case "xorb":
out = LLVMAMD64XorbNodeGen.create(srcA, srcB);
break;
case "xorw":
out = LLVMAMD64XorwNodeGen.create(srcA, srcB);
break;
case "xorl":
out = LLVMAMD64XorlNodeGen.create(srcA, srcB);
break;
case "xorq":
out = LLVMAMD64XorqNodeGen.create(srcA, srcB);
break;
case "bsrw":
out = LLVMAMD64BsrwNodeGen.create(getFlagWrite(LLVMAMD64Flags.ZF), srcA, srcB);
break;
case "bsrl":
out = LLVMAMD64BsrlNodeGen.create(getFlagWrite(LLVMAMD64Flags.ZF), srcA, srcB);
break;
case "bsrq":
out = LLVMAMD64BsrqNodeGen.create(getFlagWrite(LLVMAMD64Flags.ZF), srcA, srcB);
break;
case "bsfw":
out = LLVMAMD64BsfwNodeGen.create(getFlagWrite(LLVMAMD64Flags.ZF), srcA, srcB);
break;
case "bsfl":
out = LLVMAMD64BsflNodeGen.create(getFlagWrite(LLVMAMD64Flags.ZF), srcA, srcB);
break;
case "bsfq":
out = LLVMAMD64BsfqNodeGen.create(getFlagWrite(LLVMAMD64Flags.ZF), srcA, srcB);
break;
default:
statements.add(LLVMUnsupportedInstructionNode.create(UnsupportedReason.INLINE_ASSEMBLER, operation));
return;
}
statements.add(getOperandStore(dstType, dst, out));
}
use of com.oracle.truffle.llvm.runtime.nodes.asm.support.LLVMAMD64WriteTupelNode in project graal by oracle.
the class AsmFactory method createUnaryOperation.
void createUnaryOperation(String operation, AsmOperand operand) {
LLVMExpressionNode src;
LLVMExpressionNode out;
AsmOperand dst = operand;
Type dstType;
assert operation.length() > 0;
char suffix = operation.charAt(operation.length() - 1);
dstType = getPrimitiveTypeFromSuffix(suffix);
src = getOperandLoad(dstType, operand);
switch(operation) {
case "incb":
out = LLVMAMD64IncbNodeGen.create(getUpdatePZSOFlagsNode(), src);
break;
case "incw":
out = LLVMAMD64IncwNodeGen.create(getUpdatePZSOFlagsNode(), src);
break;
case "incl":
out = LLVMAMD64InclNodeGen.create(getUpdatePZSOFlagsNode(), src);
break;
case "incq":
out = LLVMAMD64IncqNodeGen.create(getUpdatePZSOFlagsNode(), src);
break;
case "decb":
out = LLVMAMD64DecbNodeGen.create(getUpdatePZSOFlagsNode(), src);
break;
case "decw":
out = LLVMAMD64DecwNodeGen.create(getUpdatePZSOFlagsNode(), src);
break;
case "decl":
out = LLVMAMD64DeclNodeGen.create(getUpdatePZSOFlagsNode(), src);
break;
case "decq":
out = LLVMAMD64DecqNodeGen.create(getUpdatePZSOFlagsNode(), src);
break;
case "negb":
out = LLVMAMD64NegbNodeGen.create(getUpdateCPZSOFlagsNode(), src);
break;
case "negw":
out = LLVMAMD64NegwNodeGen.create(getUpdateCPZSOFlagsNode(), src);
break;
case "negl":
out = LLVMAMD64NeglNodeGen.create(getUpdateCPZSOFlagsNode(), src);
break;
case "negq":
out = LLVMAMD64NegqNodeGen.create(getUpdateCPZSOFlagsNode(), src);
break;
case "notb":
out = LLVMAMD64NotbNodeGen.create(src);
break;
case "notw":
out = LLVMAMD64NotwNodeGen.create(src);
break;
case "notl":
out = LLVMAMD64NotlNodeGen.create(src);
break;
case "notq":
out = LLVMAMD64NotqNodeGen.create(src);
break;
case "idivb":
out = LLVMAMD64IdivbNodeGen.create(getOperandLoad(PrimitiveType.I16, new AsmRegisterOperand("ax")), src);
dst = new AsmRegisterOperand("ax");
dstType = PrimitiveType.I16;
break;
case "idivw":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("ax"), getRegisterStore("dx"));
LLVMExpressionNode high = getOperandLoad(PrimitiveType.I16, new AsmRegisterOperand("dx"));
statements.add(LLVMAMD64IdivwNodeGen.create(res, high, getOperandLoad(PrimitiveType.I16, new AsmRegisterOperand("ax")), src));
return;
}
case "idivl":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("eax"), getRegisterStore("edx"));
LLVMExpressionNode high = getOperandLoad(PrimitiveType.I32, new AsmRegisterOperand("edx"));
statements.add(LLVMAMD64IdivlNodeGen.create(res, high, getOperandLoad(PrimitiveType.I32, new AsmRegisterOperand("eax")), src));
return;
}
case "idivq":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("rax"), getRegisterStore("rdx"));
LLVMExpressionNode high = getOperandLoad(PrimitiveType.I64, new AsmRegisterOperand("rdx"));
statements.add(LLVMAMD64IdivqNodeGen.create(res, high, getOperandLoad(PrimitiveType.I64, new AsmRegisterOperand("rax")), src));
return;
}
case "imulb":
{
LLVMAMD64WriteValueNode res = getRegisterStore("ax");
statements.add(LLVMAMD64ImulbNodeGen.create(getFlagWrite(LLVMAMD64Flags.CF), getFlagWrite(LLVMAMD64Flags.PF), getFlagWrite(LLVMAMD64Flags.AF), getFlagWrite(LLVMAMD64Flags.ZF), getFlagWrite(LLVMAMD64Flags.SF), getFlagWrite(LLVMAMD64Flags.OF), res, getOperandLoad(PrimitiveType.I8, new AsmRegisterOperand("al")), src));
return;
}
case "imulw":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("ax"), getRegisterStore("dx"));
statements.add(LLVMAMD64ImulwNodeGen.create(getFlagWrite(LLVMAMD64Flags.CF), getFlagWrite(LLVMAMD64Flags.PF), getFlagWrite(LLVMAMD64Flags.AF), getFlagWrite(LLVMAMD64Flags.ZF), getFlagWrite(LLVMAMD64Flags.SF), getFlagWrite(LLVMAMD64Flags.OF), res, getOperandLoad(PrimitiveType.I16, new AsmRegisterOperand("ax")), src));
return;
}
case "imull":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("eax"), getRegisterStore("edx"));
statements.add(LLVMAMD64ImullNodeGen.create(getFlagWrite(LLVMAMD64Flags.CF), getFlagWrite(LLVMAMD64Flags.PF), getFlagWrite(LLVMAMD64Flags.AF), getFlagWrite(LLVMAMD64Flags.ZF), getFlagWrite(LLVMAMD64Flags.SF), getFlagWrite(LLVMAMD64Flags.OF), res, getOperandLoad(PrimitiveType.I32, new AsmRegisterOperand("eax")), src));
return;
}
case "imulq":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("rax"), getRegisterStore("rdx"));
statements.add(LLVMAMD64ImulqNodeGen.create(getFlagWrite(LLVMAMD64Flags.CF), getFlagWrite(LLVMAMD64Flags.PF), getFlagWrite(LLVMAMD64Flags.AF), getFlagWrite(LLVMAMD64Flags.ZF), getFlagWrite(LLVMAMD64Flags.SF), getFlagWrite(LLVMAMD64Flags.OF), res, getOperandLoad(PrimitiveType.I64, new AsmRegisterOperand("rax")), src));
return;
}
case "divb":
{
LLVMAMD64WriteValueNode res = getRegisterStore("ax");
statements.add(LLVMAMD64DivbNodeGen.create(res, getOperandLoad(PrimitiveType.I16, new AsmRegisterOperand("ax")), src));
return;
}
case "divw":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("ax"), getRegisterStore("dx"));
LLVMExpressionNode high = getOperandLoad(PrimitiveType.I16, new AsmRegisterOperand("dx"));
statements.add(LLVMAMD64DivwNodeGen.create(res, high, getOperandLoad(PrimitiveType.I16, new AsmRegisterOperand("ax")), src));
return;
}
case "divl":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("eax"), getRegisterStore("edx"));
LLVMExpressionNode high = getOperandLoad(PrimitiveType.I32, new AsmRegisterOperand("edx"));
statements.add(LLVMAMD64DivlNodeGen.create(res, high, getOperandLoad(PrimitiveType.I32, new AsmRegisterOperand("eax")), src));
return;
}
case "divq":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("rax"), getRegisterStore("rdx"));
LLVMExpressionNode high = getOperandLoad(PrimitiveType.I64, new AsmRegisterOperand("rdx"));
statements.add(LLVMAMD64DivqNodeGen.create(res, high, getOperandLoad(PrimitiveType.I64, new AsmRegisterOperand("rax")), src));
return;
}
case "mulb":
{
LLVMAMD64WriteValueNode res = getRegisterStore("ax");
statements.add(LLVMAMD64MulbNodeGen.create(getFlagWrite(LLVMAMD64Flags.CF), getFlagWrite(LLVMAMD64Flags.PF), getFlagWrite(LLVMAMD64Flags.AF), getFlagWrite(LLVMAMD64Flags.ZF), getFlagWrite(LLVMAMD64Flags.SF), getFlagWrite(LLVMAMD64Flags.OF), res, getOperandLoad(PrimitiveType.I8, new AsmRegisterOperand("al")), src));
return;
}
case "mulw":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("ax"), getRegisterStore("dx"));
statements.add(LLVMAMD64MulwNodeGen.create(getFlagWrite(LLVMAMD64Flags.CF), getFlagWrite(LLVMAMD64Flags.PF), getFlagWrite(LLVMAMD64Flags.AF), getFlagWrite(LLVMAMD64Flags.ZF), getFlagWrite(LLVMAMD64Flags.SF), getFlagWrite(LLVMAMD64Flags.OF), res, getOperandLoad(PrimitiveType.I16, new AsmRegisterOperand("ax")), src));
return;
}
case "mull":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("eax"), getRegisterStore("edx"));
statements.add(LLVMAMD64MullNodeGen.create(getFlagWrite(LLVMAMD64Flags.CF), getFlagWrite(LLVMAMD64Flags.PF), getFlagWrite(LLVMAMD64Flags.AF), getFlagWrite(LLVMAMD64Flags.ZF), getFlagWrite(LLVMAMD64Flags.SF), getFlagWrite(LLVMAMD64Flags.OF), res, getOperandLoad(PrimitiveType.I32, new AsmRegisterOperand("eax")), src));
return;
}
case "mulq":
{
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(getRegisterStore("rax"), getRegisterStore("rdx"));
statements.add(LLVMAMD64MulqNodeGen.create(getFlagWrite(LLVMAMD64Flags.CF), getFlagWrite(LLVMAMD64Flags.PF), getFlagWrite(LLVMAMD64Flags.AF), getFlagWrite(LLVMAMD64Flags.ZF), getFlagWrite(LLVMAMD64Flags.SF), getFlagWrite(LLVMAMD64Flags.OF), res, getOperandLoad(PrimitiveType.I64, new AsmRegisterOperand("rax")), src));
return;
}
case "bswapl":
out = LLVMAMD64BswaplNodeGen.create(src);
break;
case "bswapq":
out = LLVMAMD64BswapqNodeGen.create(src);
break;
case "popw":
out = LLVMAMD64PopwNodeGen.create(stackAccess);
break;
case "popl":
out = LLVMAMD64PoplNodeGen.create(stackAccess);
break;
case "popq":
out = LLVMAMD64PopqNodeGen.create(stackAccess);
break;
case "pushw":
statements.add(LLVMAMD64PushwNodeGen.create(stackAccess, src));
return;
case "pushl":
statements.add(LLVMAMD64PushlNodeGen.create(stackAccess, src));
return;
case "pushq":
statements.add(LLVMAMD64PushqNodeGen.create(stackAccess, src));
return;
default:
statements.add(LLVMUnsupportedInstructionNode.create(UnsupportedReason.INLINE_ASSEMBLER, operation));
return;
}
statements.add(maybeMakeAtomic(getOperandStore(dstType, dst, out), dst));
}
use of com.oracle.truffle.llvm.runtime.nodes.asm.support.LLVMAMD64WriteTupelNode in project graal by oracle.
the class AsmFactory method createBinaryOperationImplicitSize.
void createBinaryOperationImplicitSize(String operation, AsmOperand a, AsmOperand b) {
AsmOperand dst = b;
AsmOperand src = a;
assert a != null && b != null;
Type dstType = getType(b, a);
LLVMExpressionNode srcA;
LLVMExpressionNode srcB;
LLVMExpressionNode out;
switch(operation) {
case "lea":
out = getOperandAddress(dstType, src);
if (isLeaPointer(src)) {
dstType = new PointerType(dstType);
}
break;
case "xor":
srcA = getOperandLoad(dstType, a);
srcB = getOperandLoad(dstType, b);
switch(getPrimitiveType(dstType)) {
case I8:
out = LLVMAMD64XorbNodeGen.create(srcA, srcB);
break;
case I16:
out = LLVMAMD64XorwNodeGen.create(srcA, srcB);
break;
case I32:
out = LLVMAMD64XorlNodeGen.create(srcA, srcB);
break;
case I64:
out = LLVMAMD64XorqNodeGen.create(srcA, srcB);
break;
default:
throw invalidOperandType(dstType);
}
break;
case "mov":
if (dstType instanceof PrimitiveType || dstType instanceof PointerType) {
out = getOperandLoad(dstType, a);
} else {
throw invalidOperandType(dstType);
}
break;
case "bsr":
srcA = getOperandLoad(dstType, a);
srcB = getOperandLoad(dstType, b);
switch(getPrimitiveType(dstType)) {
case I16:
out = LLVMAMD64BsrwNodeGen.create(getFlagWrite(LLVMAMD64Flags.ZF), srcA, srcB);
break;
case I32:
out = LLVMAMD64BsrlNodeGen.create(getFlagWrite(LLVMAMD64Flags.ZF), srcA, srcB);
break;
case I64:
out = LLVMAMD64BsrqNodeGen.create(getFlagWrite(LLVMAMD64Flags.ZF), srcA, srcB);
break;
default:
throw invalidOperandType(dstType);
}
break;
case "bsf":
srcA = getOperandLoad(dstType, a);
srcB = getOperandLoad(dstType, b);
switch(getPrimitiveType(dstType)) {
case I16:
out = LLVMAMD64BsfwNodeGen.create(getFlagWrite(LLVMAMD64Flags.ZF), srcA, srcB);
break;
case I32:
out = LLVMAMD64BsflNodeGen.create(getFlagWrite(LLVMAMD64Flags.ZF), srcA, srcB);
break;
case I64:
out = LLVMAMD64BsfqNodeGen.create(getFlagWrite(LLVMAMD64Flags.ZF), srcA, srcB);
break;
default:
throw invalidOperandType(dstType);
}
break;
case "xchg":
{
LLVMStatementNode res;
XchgOperands operands = new XchgOperands(a, b, dstType);
switch(getPrimitiveType(dstType)) {
case I8:
res = LLVMAMD64XchgbNodeGen.create(operands.dst, operands.srcA, operands.srcB);
break;
case I16:
res = LLVMAMD64XchgwNodeGen.create(operands.dst, operands.srcA, operands.srcB);
break;
case I32:
res = LLVMAMD64XchglNodeGen.create(operands.dst, operands.srcA, operands.srcB);
break;
case I64:
res = LLVMAMD64XchgqNodeGen.create(operands.dst, operands.srcA, operands.srcB);
break;
default:
throw invalidOperandType(dstType);
}
/**
* Make xchg unconditionally atomic. Some code (e.g. musl libc) using xchg relies on
* its (and any other instruction's) non-atomic behavior in concurrency with other
* locked/atomic instructions to be atomic.
*
* The issue is that we should avoid globally locking memory operations, and so
* instead we hand-pick instructions that are used in code related to
* synchronization, and xchg is one of those (e.g. in the musl libc). This is not
* entirely correct behavior, but should cover most practical use-cases.
*/
statements.add(makeAtomic(res, b));
return;
}
case "cmpxchg":
{
srcA = getOperandLoad(dstType, a);
srcB = getOperandLoad(dstType, b);
LLVMAMD64WriteValueNode dst1 = getStore(dstType, b);
LLVMAMD64WriteValueNode dst2;
LLVMExpressionNode accumulator;
LLVMStatementNode res;
if (dstType instanceof PointerType) {
dst2 = getRegisterStore("rax");
accumulator = getOperandLoad(new PointerType(PrimitiveType.I8), new AsmRegisterOperand("rax"));
res = LLVMAMD64CmpXchgqNodeGen.create(getUpdateCPAZSOFlagsNode(), dst1, dst2, accumulator, srcA, srcB);
} else {
switch(getPrimitiveType(dstType)) {
case I8:
dst2 = getRegisterStore("al");
accumulator = getOperandLoad(PrimitiveType.I8, new AsmRegisterOperand("al"));
res = LLVMAMD64CmpXchgbNodeGen.create(getUpdateCPAZSOFlagsNode(), dst1, dst2, accumulator, srcA, srcB);
break;
case I16:
dst2 = getRegisterStore("ax");
accumulator = getOperandLoad(PrimitiveType.I16, new AsmRegisterOperand("ax"));
res = LLVMAMD64CmpXchgwNodeGen.create(getUpdateCPAZSOFlagsNode(), dst1, dst2, accumulator, srcA, srcB);
break;
case I32:
dst2 = getRegisterStore("eax");
accumulator = getOperandLoad(PrimitiveType.I32, new AsmRegisterOperand("eax"));
res = LLVMAMD64CmpXchglNodeGen.create(getUpdateCPAZSOFlagsNode(), dst1, dst2, accumulator, srcA, srcB);
break;
case I64:
dst2 = getRegisterStore("rax");
accumulator = getOperandLoad(PrimitiveType.I64, new AsmRegisterOperand("rax"));
res = LLVMAMD64CmpXchgqNodeGen.create(getUpdateCPAZSOFlagsNode(), dst1, dst2, accumulator, srcA, srcB);
break;
default:
throw invalidOperandType(dstType);
}
}
statements.add(maybeMakeAtomic(res, b));
return;
}
case "and":
srcA = getOperandLoad(dstType, a);
srcB = getOperandLoad(dstType, b);
switch(getPrimitiveType(dstType)) {
case I8:
out = LLVMAMD64AndbNodeGen.create(getUpdatePZSFlagsNode(), srcA, srcB);
break;
case I16:
out = LLVMAMD64AndwNodeGen.create(getUpdatePZSFlagsNode(), srcA, srcB);
break;
case I32:
out = LLVMAMD64AndlNodeGen.create(getUpdatePZSFlagsNode(), srcA, srcB);
break;
case I64:
out = LLVMAMD64AndqNodeGen.create(getUpdatePZSFlagsNode(), srcA, srcB);
break;
default:
throw invalidOperandType(dstType);
}
break;
case "or":
srcA = getOperandLoad(dstType, a);
srcB = getOperandLoad(dstType, b);
switch(getPrimitiveType(dstType)) {
case I8:
out = LLVMAMD64OrbNodeGen.create(srcA, srcB);
break;
case I16:
out = LLVMAMD64OrwNodeGen.create(srcA, srcB);
break;
case I32:
out = LLVMAMD64OrlNodeGen.create(srcA, srcB);
break;
case I64:
out = LLVMAMD64OrqNodeGen.create(srcA, srcB);
break;
default:
throw invalidOperandType(dstType);
}
break;
case "pmovmskb":
srcA = getOperandLoad(getType(a), a);
LLVMX86_ConversionNode.LLVMX86_Pmovmskb128 pmovmskb128 = LLVMX86_ConversionNodeFactory.LLVMX86_Pmovmskb128NodeGen.create(srcA);
out = pmovmskb128;
break;
case "xadd":
srcA = getOperandLoad(dstType, a);
srcB = getOperandLoad(dstType, b);
switch(getPrimitiveType(dstType)) {
case I8:
{
LLVMAMD64WriteValueNode dst1 = getRegisterStore(PrimitiveType.I8, a);
LLVMAMD64WriteValueNode dst2 = getStore(dstType, dst);
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(dst1, dst2);
statements.add(maybeMakeAtomic(LLVMAMD64XaddbNodeGen.create(getUpdateCPZSOFlagsNode(), res, srcA, srcB), b));
return;
}
case I16:
{
LLVMAMD64WriteValueNode dst1 = getRegisterStore(PrimitiveType.I16, a);
LLVMAMD64WriteValueNode dst2 = getStore(dstType, dst);
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(dst1, dst2);
statements.add(maybeMakeAtomic(LLVMAMD64XaddwNodeGen.create(getUpdateCPZSOFlagsNode(), res, srcA, srcB), b));
return;
}
case I32:
{
LLVMAMD64WriteValueNode dst1 = getRegisterStore(PrimitiveType.I32, a);
LLVMAMD64WriteValueNode dst2 = getStore(dstType, dst);
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(dst1, dst2);
statements.add(maybeMakeAtomic(LLVMAMD64XaddlNodeGen.create(getUpdateCPZSOFlagsNode(), res, srcA, srcB), b));
return;
}
case I64:
{
LLVMAMD64WriteValueNode dst1 = getRegisterStore(PrimitiveType.I64, a);
LLVMAMD64WriteValueNode dst2 = getStore(dstType, dst);
LLVMAMD64WriteTupelNode res = LLVMAMD64WriteTupelNodeGen.create(dst1, dst2);
statements.add(maybeMakeAtomic(LLVMAMD64XaddqNodeGen.create(getUpdateCPZSOFlagsNode(), res, srcA, srcB), b));
return;
}
default:
throw invalidOperandType(dstType);
}
default:
statements.add(LLVMUnsupportedInstructionNode.create(UnsupportedReason.INLINE_ASSEMBLER, operation));
return;
}
statements.add(getOperandStore(dstType, dst, out));
}
Aggregations