Exemplo n.º 1
0
static InstTransResult doXaddRR(InstPtr ip,    BasicBlock *&b,
                            const MCOperand &dstReg,
                            const MCOperand &srcReg) 
{
    NASSERT(dstReg.isReg());
    NASSERT(srcReg.isReg());

    Value   *dstReg_v = R_READ<width>(b, dstReg.getReg());
    Value   *srcReg_v = R_READ<width>(b, srcReg.getReg());

    Value   *res = BinaryOperator::CreateAdd(dstReg_v, srcReg_v, "", b);

    R_WRITE<width>(b, dstReg.getReg(), res);
    R_WRITE<width>(b, srcReg.getReg(), dstReg_v);

    //write the flag updates
    //compute AF
    WriteAFAddSub<width>(b, res, dstReg_v, srcReg_v);
    //compute SF
    WriteSF<width>(b, res);
    //compute ZF
    WriteZF<width>(b, res);
    //compute OF
    WriteOFAdd<width>(b, res, dstReg_v, srcReg_v);
    //compute PF
    WritePF<width>(b, res);
    //compute CF*/
    WriteCFAdd<width>(b, res, dstReg_v);

    return ContinueBlock;
}
Exemplo n.º 2
0
static InstTransResult doSubRI(InstPtr ip, BasicBlock *&b,
                               const MCOperand &dst,
                               const MCOperand &src1,
                               const MCOperand &src2)
{
    NASSERT(src1.isReg());
    NASSERT(src2.isImm());
    NASSERT(dst.isReg());

	// Read from src1.
    Value *srcReg = R_READ<dstWidth>(b, src1.getReg());

	// Create the constant value.
	Value *c = CONST_V<srcWidth>(b, src2.getImm());
	
	CastInst *cInst = CastInst::CreateIntegerCast(c, srcReg->getType(), true, "", b);  
	
	// Do the operation.
	Value *subRes = doSubVV<dstWidth>(ip, b, srcReg, cInst);

	// Store the result in dst.
	R_WRITE<dstWidth>(b, dst.getReg(), subRes);

    return ContinueBlock;
}
Exemplo n.º 3
0
static InstTransResult doCmpxchgRR(InstPtr ip,    BasicBlock      *&b,
                            const MCOperand &dstReg,
                            const MCOperand &srcReg) 
{
    NASSERT(dstReg.isReg());
    NASSERT(srcReg.isReg());


    Value   *acc;

    switch(width) {
        case 8:
            acc = R_READ<width>(b, X86::AL);
            break;
        case 16:
            acc = R_READ<width>(b, X86::AX);
            break;
        case 32:
            acc = R_READ<width>(b, X86::EAX);
            break;
        default:
            throw TErr(__LINE__, __FILE__, "Width not supported");
    }

    Value   *dstReg_v = R_READ<width>(b, dstReg.getReg());
    Value   *srcReg_v = R_READ<width>(b, srcReg.getReg());

    doCmpVV<width>(ip, b, acc, dstReg_v);

    Value   *Cmp = new ICmpInst(*b, CmpInst::ICMP_EQ, acc, dstReg_v);

    F_WRITE(b, ZF, Cmp);

    ///
    // ZF = Acc == DST
    // acc = select(ZF, acc, dst)
    // dst = select(ZF, src, dst)
    Value *new_acc = SelectInst::Create(Cmp, acc, dstReg_v, "", b);
    Value *new_dst = SelectInst::Create(Cmp, srcReg_v, dstReg_v, "", b); 

    R_WRITE<width>(b, dstReg.getReg(), new_dst);

    switch(width) {
        case 8:
            R_WRITE<width>(b, X86::AL, new_acc);
            break;
        case 16:
            R_WRITE<width>(b, X86::AX, new_acc);
            break;
        case 32:
            R_WRITE<width>(b, X86::EAX, new_acc);
            break;
        default:
            throw TErr(__LINE__, __FILE__, "Width not supported");
    }


    return ContinueBlock;
}
Exemplo n.º 4
0
static InstTransResult doRSMov(InstPtr ip,   BasicBlock *&b,
                            const MCOperand &dst,
                            const MCOperand &src)
{
    NASSERT(dst.isReg());
    NASSERT(src.isReg());

    Value *seg_val = getSegmentValue<width>(b, src.getReg());
    R_WRITE<width>(b, dst.getReg(), seg_val);
    return ContinueBlock;
}
Exemplo n.º 5
0
static InstTransResult do_SSE_RR(InstPtr ip, BasicBlock *& block, 
                                const MCOperand &o1,
                                const MCOperand &o2)
{
    NASSERT(o1.isReg());
    NASSERT(o2.isReg());

    Value *opVal1 = R_READ<fpwidth>(block, o1.getReg());
    Value *opVal2 = R_READ<fpwidth>(block, o2.getReg());

    return do_SSE_VV<fpwidth, bin_op>(o1.getReg(), block, opVal1, opVal2);
}
Exemplo n.º 6
0
static InstTransResult doPSHUFDri(BasicBlock *&b, const MCOperand &dst, const MCOperand &src, const MCOperand &order)
{
    NASSERT(dst.isReg());
    NASSERT(src.isReg());
    NASSERT(order.isImm());

    Value *input = R_READ<128>(b, src.getReg());
    
    Value *shuffled = doShuffle<128,32>(b, input, order.getImm());

    R_WRITE<128>(b, dst.getReg(), shuffled);
    return ContinueBlock;
}
Exemplo n.º 7
0
static InstTransResult doPUNPCKrr(
        BasicBlock *&b, 
        const MCOperand &dst, 
        const MCOperand &src)
{
    NASSERT(dst.isReg());
    NASSERT(src.isReg());

    Value *srcVal = R_READ<width>(b, src.getReg());
    Value *dstVal = R_READ<width>(b, dst.getReg());

    return doPUNPCKVV<width, slice_width>(b, dst, srcVal, dstVal);
}
Exemplo n.º 8
0
static InstTransResult doMovSXRR(InstPtr ip, 	BasicBlock *&b,
							const MCOperand	&dst,
							const MCOperand &src)
{
	NASSERT(dst.isReg());
	NASSERT(src.isReg());

	Value	*r = doMovSXV<dstWidth>(ip, b, R_READ<srcWidth>(b, src.getReg()));

	R_WRITE<dstWidth>(b, dst.getReg(), r);

	return ContinueBlock;
}
Exemplo n.º 9
0
static InstTransResult doUCOMISrr(BasicBlock *&b, const MCOperand &op1, const MCOperand &op2)
{
    NASSERT(op1.isReg());
    NASSERT(op2.isReg());

    Value *op1_val = R_READ<width>(b, op1.getReg());
    Value *op2_val = R_READ<width>(b, op2.getReg());

    Value *fp1_val = INT_AS_FP<width>(b, op1_val);
    Value *fp2_val = INT_AS_FP<width>(b, op2_val);

    return doUCOMISvv(b, fp1_val, fp2_val);

}
Exemplo n.º 10
0
static InstTransResult doPINSRWrri(BasicBlock *&b, const MCOperand &dst, const MCOperand &src, const MCOperand &order)
{
    NASSERT(dst.isReg());
    NASSERT(src.isReg());
    NASSERT(order.isImm());

    Value *vec = R_READ<128>(b, dst.getReg());
    Value *elem = R_READ<16>(b, src.getReg());
    
    Value *new_vec = doInsertion<128,16>(b, vec, elem, order.getImm());

    R_WRITE<128>(b, dst.getReg(), new_vec);
    return ContinueBlock;
}
Exemplo n.º 11
0
static InstTransResult doBsrr(
        BasicBlock *&b, 
        const MCOperand &dst,
        const MCOperand &src)
{

    TASSERT(dst.isReg(), "operand must be register");
    TASSERT(src.isReg(), "operand must be register");

    Value *src_val = R_READ<width>(b, src.getReg());

    Type *s[1] = { Type::getIntNTy(b->getContext(), width) };
    Function *ctlzFn = Intrinsic::getDeclaration(b->getParent()->getParent(), Intrinsic::ctlz, s);

    TASSERT(ctlzFn != NULL, "Could not find ctlz intrinsic");

    vector<Value*>  ctlzArgs;
    ctlzArgs.push_back(src_val);
    ctlzArgs.push_back(CONST_V<1>(b, 0));
    Value *ctlz = CallInst::Create(ctlzFn, ctlzArgs, "", b);

    Value *index_of_first_1 = BinaryOperator::CreateSub(
                CONST_V<width>(b, width),
                ctlz,
                "", b);

    Value *is_zero = new ICmpInst(
            *b,
            CmpInst::ICMP_EQ,
            CONST_V<width>(b, 0),
            index_of_first_1);

    F_WRITE(b, ZF, is_zero);

    Value *fix_index = BinaryOperator::CreateSub(
                    index_of_first_1,
                    CONST_V<width>(b, 1),
                    "", b);

    // See if we write to register
    Value *save_index = SelectInst::Create(
            is_zero, // check if the source was zero
            src_val, // if it was, do not change contents
            fix_index,  // if it was not, set index
            "", b);

    R_WRITE<width>(b, dst.getReg(), save_index);

    return ContinueBlock;
}
Exemplo n.º 12
0
static InstTransResult doXchgRR(InstPtr ip,    BasicBlock *&b, 
                            const MCOperand &o1,
                            const MCOperand &o2)
{
    NASSERT(o1.isReg());
    NASSERT(o2.isReg());

    Value   *t1 = R_READ<width>(b, o1.getReg());
    Value   *t2 = R_READ<width>(b, o2.getReg());

    R_WRITE<width>(b, o2.getReg(), t1);
    R_WRITE<width>(b, o1.getReg(), t2);

    return ContinueBlock;
}
Exemplo n.º 13
0
static InstTransResult MOVAndZextRR(BasicBlock *& block, const MCOperand &dst, const MCOperand &src) {
    NASSERT(src.isReg());

    Value *src_val = R_READ<width>(block, src.getReg());

    return MOVAndZextRV<width>(block, dst, src_val);
}
Exemplo n.º 14
0
static InstTransResult doBswapR(InstPtr ip,   BasicBlock *&b,
                            const MCOperand &reg) 
{
    TASSERT(reg.isReg(), "");

    if(width != 32)
    {
        throw TErr(__LINE__, __FILE__, "Width not supported");
    }

    Value   *tmp = R_READ<width>(b, reg.getReg());

    // Create the new bytes from the original value
    Value   *newByte1 = BinaryOperator::CreateShl(tmp, CONST_V<width>(b, 24), "", b);
    Value   *newByte2 = BinaryOperator::CreateShl(BinaryOperator::CreateAnd(tmp, CONST_V<width>(b, 0x0000FF00), "", b),
                                                    CONST_V<width>(b, 8),
                                                    "",
                                                    b);
    Value   *newByte3 = BinaryOperator::CreateLShr(BinaryOperator::CreateAnd(tmp, CONST_V<width>(b, 0x00FF0000), "", b),
                                                    CONST_V<width>(b, 8),
                                                    "",
                                                    b);
    Value   *newByte4 = BinaryOperator::CreateLShr(tmp, CONST_V<width>(b, 24), "", b);
    
    // Add the bytes together to make the resulting DWORD
    Value   *res = BinaryOperator::CreateAdd(newByte1, newByte2, "", b);
    res = BinaryOperator::CreateAdd(res, newByte3, "", b);
    res = BinaryOperator::CreateAdd(res, newByte4, "", b);

    R_WRITE<width>(b, reg.getReg(), res);

    return ContinueBlock;
}
Exemplo n.º 15
0
static InstTransResult doXorRI(InstPtr ip, BasicBlock *&b,
                               const MCOperand &dst,
                               const MCOperand &o1,
                               const MCOperand &o2)
{
    TASSERT(dst.isReg(), "");
    TASSERT(o1.isReg(), "");
    TASSERT(o2.isImm(), "");

    Value *o1_v = R_READ<width>(b, o1.getReg());
    Value *o2_v = CONST_V<width>(b, o2.getImm());

    R_WRITE<width>(b, dst.getReg(), doXorVV<width>(ip, b, o1_v, o2_v));

    return ContinueBlock;
}
Exemplo n.º 16
0
static InstTransResult doOrRM(InstPtr ip, BasicBlock *&b,
                              Value           *addr,
                              const MCOperand &o1,
                              const MCOperand &dst)
{
    TASSERT(addr != NULL, "");
    TASSERT(o1.isReg(), "");
    TASSERT(dst.isReg(), "");

    Value *addr_v = M_READ<width>(ip, b, addr);
    Value *o1_v = R_READ<width>(b, o1.getReg());

    R_WRITE<width>(b, dst.getReg(), doOrVV<width>(ip, b, addr_v, o1_v));

    return ContinueBlock;
}
Exemplo n.º 17
0
static InstTransResult doIMulR(InstPtr ip,    BasicBlock *&b, 
                           const MCOperand &src)
{
    NASSERT(src.isReg());

    Value   *res = doIMulV<width>(ip, b, R_READ<width>(b, src.getReg()));

    Type    *t = Type::getIntNTy(b->getContext(), width);
    Value   *res_sh = BinaryOperator::Create(Instruction::LShr, res, CONST_V<width*2>(b, width), "", b);
    Value   *wrAX = new TruncInst(res, t, "", b);
    Value   *wrDX = new TruncInst(res_sh, t, "", b);

    switch(width) {
        case 8:
            R_WRITE<width>(b, X86::AH, wrDX);
            R_WRITE<width>(b, X86::AL, wrAX);
            break;
        case 16:
            R_WRITE<width>(b, X86::DX, wrDX);
            R_WRITE<width>(b, X86::AX, wrAX);
            break;
        case 32:
            R_WRITE<width>(b, X86::EDX, wrDX);
            R_WRITE<width>(b, X86::EAX, wrAX);
            break;
        default:
            throw TErr(__LINE__, __FILE__, "Not supported width");
    }
    
    return ContinueBlock;
}
Exemplo n.º 18
0
static InstTransResult doMovZXRM(InstPtr ip,   BasicBlock *&b,
                            const MCOperand &dst,
                            Value *src)
{
    NASSERT(dst.isReg());
	NASSERT(src != NULL);

    if( dstWidth == 32 && 
        srcWidth == 8 && 
        ip->has_jump_index_table()) 
    {
       doJumpIndexTableViaSwitch(b, ip); 
       return ContinueBlock;
    }

    //do a read from src of the appropriate width
    Value   *fromSrc = M_READ<srcWidth>(ip, b, src);

    //extend 
    Type    *toT = Type::getIntNTy(b->getContext(), dstWidth);
    Value   *xt = new ZExtInst(fromSrc, toT, "", b);

    //write into dst
    R_WRITE<dstWidth>(b, dst.getReg(), xt);

    return ContinueBlock;
}
Exemplo n.º 19
0
uint64_t R600MCCodeEmitter::getMachineOpValue(const MCInst &MI,
                                              const MCOperand &MO,
                                        SmallVectorImpl<MCFixup> &Fixups,
                                        const MCSubtargetInfo &STI) const {
  if (MO.isReg()) {
    if (HAS_NATIVE_OPERANDS(MCII.get(MI.getOpcode()).TSFlags))
      return MRI.getEncodingValue(MO.getReg());
    return getHWReg(MO.getReg());
  }

  if (MO.isExpr()) {
    const MCSymbolRefExpr *Expr = cast<MCSymbolRefExpr>(MO.getExpr());
    // We put rodata at the end of code section, then map the entire
    // code secetion as vtx buf. Thus the section relative address is the
    // correct one.
    // Each R600 literal instruction has two operands
    // We can't easily get the order of the current one, so compare against
    // the first one and adjust offset.
    const unsigned offset = (&MO == &MI.getOperand(0)) ? 0 : 4;
    Fixups.push_back(MCFixup::create(offset, Expr, FK_SecRel_4, MI.getLoc()));
    return 0;
  }

  assert(MO.isImm());
  return MO.getImm();
}
Exemplo n.º 20
0
unsigned SparcMCCodeEmitter::
getMachineOpValue(const MCInst &MI, const MCOperand &MO,
                  SmallVectorImpl<MCFixup> &Fixups,
                  const MCSubtargetInfo &STI) const {

  if (MO.isReg())
    return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());

  if (MO.isImm())
    return MO.getImm();

  assert(MO.isExpr());
  const MCExpr *Expr = MO.getExpr();
  if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Expr)) {
    MCFixupKind Kind = (MCFixupKind)SExpr->getFixupKind();
    Fixups.push_back(MCFixup::create(0, Expr, Kind));
    return 0;
  }

  int64_t Res;
  if (Expr->evaluateAsAbsolute(Res))
    return Res;

  llvm_unreachable("Unhandled expression!");
  return 0;
}
Exemplo n.º 21
0
static InstTransResult doXorRM(InstPtr ip, BasicBlock *&b,
                               const MCOperand &dst,
                               const MCOperand &src1,
                               Value           *mem)
{
    TASSERT(mem != NULL, "");
    TASSERT(dst.isReg(), "");
    TASSERT(src1.isReg(), "");

    Value *fromMem = M_READ<width>(ip, b, mem);
    Value *fromReg = R_READ<width>(b, src1.getReg());
    Value *res = doXorVV<width>(ip, b, fromMem, fromReg);
    R_WRITE<width>(b, dst.getReg(), res);

    return ContinueBlock;
}
Exemplo n.º 22
0
static InstTransResult doPSRArr(BasicBlock *&b, const MCOperand &dst, const MCOperand &src)
{
    NASSERT(src.isReg());

    Value *shift_count = R_READ<128>(b, src.getReg());

    return doNewShift<width, Instruction::AShr>(b, dst, shift_count, nullptr);
}
Exemplo n.º 23
0
static InstTransResult doPSLLrr(BasicBlock *&b, const MCOperand &dst, const MCOperand &src)
{
    NASSERT(src.isReg());

    Value *shift_count = R_READ<128>(b, src.getReg());

    return doNewShift<width, Instruction::Shl>(b, dst, shift_count, CONST_V<128>(b, 0));
}
Exemplo n.º 24
0
static InstTransResult doXorRR(InstPtr ip, BasicBlock *&b,
                               const MCOperand &dst,
                               const MCOperand &o1,
                               const MCOperand &o2)
{
    TASSERT(dst.isReg(), "");
    TASSERT(o1.isReg(), "");
    TASSERT(o2.isReg(), "");

    // Read the sources.
    Value *o1_v = R_READ<width>(b, o1.getReg());
    Value *o2_v = R_READ<width>(b, o2.getReg());

	// Do the operation.
	R_WRITE<width>(b, dst.getReg(), doXorVV<width>(ip, b, o1_v, o2_v));

    return ContinueBlock;
}
Exemplo n.º 25
0
static InstTransResult doSbbRR(InstPtr ip, BasicBlock *&b,
                               const MCOperand &o1,
                               const MCOperand &o2, 
                               const MCOperand &dst)
{
    NASSERT(o1.isReg());
    NASSERT(o2.isReg());
    NASSERT(dst.isReg());

    Value *r1 = R_READ<width>(b, o1.getReg());
    Value *r2 = R_READ<width>(b, o2.getReg());

    Value *res = doSbbVV<width>(ip, b, r1, r2);

    R_WRITE<width>(b, dst.getReg(), res);

    return ContinueBlock;
}
Exemplo n.º 26
0
static InstTransResult doSbbRM(InstPtr ip, BasicBlock *&b,
                               const MCOperand &o1,
                               Value           *addr,
                               const MCOperand &dst)
{
    NASSERT(o1.isReg());
    NASSERT(addr != NULL);
    NASSERT(dst.isReg());

    Value *r1 = R_READ<width>(b, o1.getReg());
    Value *mem_v = M_READ<width>(ip, b, addr);

    Value *res = doSbbVV<width>(ip, b, r1, mem_v);

    R_WRITE<width>(b, dst.getReg(), res);

    return ContinueBlock;
}
Exemplo n.º 27
0
static InstTransResult doSubRM(InstPtr ip, BasicBlock *&b,
                               Value           *addr,
                               const MCOperand &o1,
                               const MCOperand &o2)
{
    NASSERT(addr != NULL);
    NASSERT(o1.isReg());
    NASSERT(o2.isReg());

    Value *lhs = R_READ<width>(b, o1.getReg());
    Value *rhs = M_READ<width>(ip, b, addr);

    Value *res = doSubVV<width>(ip, b, lhs, rhs);

    R_WRITE<width>(b, o2.getReg(), res);

    return ContinueBlock;
}
Exemplo n.º 28
0
static InstTransResult doMulR(InstPtr ip,    BasicBlock *&b, 
                           const MCOperand &src)
{
    NASSERT(src.isReg());

    doMulV<width>(ip, b, R_READ<width>(b, src.getReg()));

    return ContinueBlock;
}
Exemplo n.º 29
0
static InstTransResult doIMulRRI(InstPtr ip,   BasicBlock      *&b,
                            const MCOperand &dst,
                            const MCOperand &lhs,
                            const MCOperand &rhs)
{
    NASSERT(dst.isReg());
    NASSERT(lhs.isReg());
    NASSERT(rhs.isImm());

    Value   *res = 
        doIMulVVV<width>(ip, b,
                        R_READ<width>(b, lhs.getReg()),
                        CONST_V<width>(b, rhs.getImm()));

    R_WRITE<width>(b, dst.getReg(), res);

    return ContinueBlock;
}
Exemplo n.º 30
0
/// getMachineOpValue - Return binary encoding of operand. If the machine
/// operand requires relocation, record the relocation and return zero.
unsigned
AArch64MCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
                                        SmallVectorImpl<MCFixup> &Fixups,
                                        const MCSubtargetInfo &STI) const {
  if (MO.isReg())
    return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());

  assert(MO.isImm() && "did not expect relocated expression");
  return static_cast<unsigned>(MO.getImm());
}