Search in sources :

Example 1 with LLVMAMD64WriteTupelNode

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));
}
Also used : PrimitiveType(com.oracle.truffle.llvm.runtime.types.PrimitiveType) VectorType(com.oracle.truffle.llvm.runtime.types.VectorType) PointerType(com.oracle.truffle.llvm.runtime.types.PointerType) StructureType(com.oracle.truffle.llvm.runtime.types.StructureType) VoidType(com.oracle.truffle.llvm.runtime.types.VoidType) Type(com.oracle.truffle.llvm.runtime.types.Type) LLVMAMD64WriteValueNode(com.oracle.truffle.llvm.runtime.nodes.asm.support.LLVMAMD64WriteValueNode) LLVMAMD64WriteTupelNode(com.oracle.truffle.llvm.runtime.nodes.asm.support.LLVMAMD64WriteTupelNode) LLVMExpressionNode(com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode)

Example 2 with LLVMAMD64WriteTupelNode

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));
}
Also used : PrimitiveType(com.oracle.truffle.llvm.runtime.types.PrimitiveType) VectorType(com.oracle.truffle.llvm.runtime.types.VectorType) PointerType(com.oracle.truffle.llvm.runtime.types.PointerType) StructureType(com.oracle.truffle.llvm.runtime.types.StructureType) VoidType(com.oracle.truffle.llvm.runtime.types.VoidType) Type(com.oracle.truffle.llvm.runtime.types.Type) LLVMAMD64WriteValueNode(com.oracle.truffle.llvm.runtime.nodes.asm.support.LLVMAMD64WriteValueNode) LLVMAMD64WriteTupelNode(com.oracle.truffle.llvm.runtime.nodes.asm.support.LLVMAMD64WriteTupelNode) LLVMExpressionNode(com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode)

Example 3 with LLVMAMD64WriteTupelNode

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));
}
Also used : LLVMX86_ConversionNode(com.oracle.truffle.llvm.runtime.nodes.intrinsics.llvm.x86.LLVMX86_ConversionNode) PrimitiveType(com.oracle.truffle.llvm.runtime.types.PrimitiveType) VectorType(com.oracle.truffle.llvm.runtime.types.VectorType) PointerType(com.oracle.truffle.llvm.runtime.types.PointerType) StructureType(com.oracle.truffle.llvm.runtime.types.StructureType) VoidType(com.oracle.truffle.llvm.runtime.types.VoidType) Type(com.oracle.truffle.llvm.runtime.types.Type) LLVMAMD64WriteValueNode(com.oracle.truffle.llvm.runtime.nodes.asm.support.LLVMAMD64WriteValueNode) LLVMAMD64WriteTupelNode(com.oracle.truffle.llvm.runtime.nodes.asm.support.LLVMAMD64WriteTupelNode) LLVMStatementNode(com.oracle.truffle.llvm.runtime.nodes.api.LLVMStatementNode) LLVMExpressionNode(com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode) PointerType(com.oracle.truffle.llvm.runtime.types.PointerType) PrimitiveType(com.oracle.truffle.llvm.runtime.types.PrimitiveType)

Aggregations

LLVMExpressionNode (com.oracle.truffle.llvm.runtime.nodes.api.LLVMExpressionNode)3 LLVMAMD64WriteTupelNode (com.oracle.truffle.llvm.runtime.nodes.asm.support.LLVMAMD64WriteTupelNode)3 LLVMAMD64WriteValueNode (com.oracle.truffle.llvm.runtime.nodes.asm.support.LLVMAMD64WriteValueNode)3 PointerType (com.oracle.truffle.llvm.runtime.types.PointerType)3 PrimitiveType (com.oracle.truffle.llvm.runtime.types.PrimitiveType)3 StructureType (com.oracle.truffle.llvm.runtime.types.StructureType)3 Type (com.oracle.truffle.llvm.runtime.types.Type)3 VectorType (com.oracle.truffle.llvm.runtime.types.VectorType)3 VoidType (com.oracle.truffle.llvm.runtime.types.VoidType)3 LLVMStatementNode (com.oracle.truffle.llvm.runtime.nodes.api.LLVMStatementNode)1 LLVMX86_ConversionNode (com.oracle.truffle.llvm.runtime.nodes.intrinsics.llvm.x86.LLVMX86_ConversionNode)1