X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FARM%2FARMMCCodeEmitter.cpp;h=7f34ee96e379ed4eeebb3d0ef26d230bff9ead53;hb=c266600bec4b5ba0ee93ffdfeaafcab8f1295145;hp=df28a992913607315a114357c75022ef872d1d55;hpb=90cc533fda9742f5c67203f97e69e5efd270c676;p=oota-llvm.git diff --git a/lib/Target/ARM/ARMMCCodeEmitter.cpp b/lib/Target/ARM/ARMMCCodeEmitter.cpp index df28a992913..7f34ee96e37 100644 --- a/lib/Target/ARM/ARMMCCodeEmitter.cpp +++ b/lib/Target/ARM/ARMMCCodeEmitter.cpp @@ -45,24 +45,28 @@ public: const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const { const static MCFixupKindInfo Infos[] = { - // name off bits flags - { "fixup_arm_ldst_pcrel_12", 1, 24, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_t2_ldst_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel | +// This table *must* be in the order that the fixup_* kinds are defined in +// ARMFixupKinds.h. +// +// Name Offset (bits) Size (bits) Flags +{ "fixup_arm_ldst_pcrel_12", 1, 24, MCFixupKindInfo::FKF_IsPCRel }, +{ "fixup_t2_ldst_pcrel_12", 0, 32, MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsAligned}, - { "fixup_arm_pcrel_10", 1, 24, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_t2_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_arm_adr_pcrel_12", 1, 24, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_arm_branch", 1, 24, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_t2_branch", 0, 32, MCFixupKindInfo::FKF_IsPCRel | +{ "fixup_arm_pcrel_10", 1, 24, MCFixupKindInfo::FKF_IsPCRel }, +{ "fixup_t2_pcrel_10", 0, 32, MCFixupKindInfo::FKF_IsPCRel | MCFixupKindInfo::FKF_IsAligned}, - { "fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_arm_thumb_blx", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_arm_thumb_cb", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_arm_thumb_cp", 1, 8, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_arm_thumb_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_arm_thumb_bcc", 1, 8, MCFixupKindInfo::FKF_IsPCRel }, - { "fixup_arm_movt_hi16", 0, 16, 0 }, - { "fixup_arm_movw_lo16", 0, 16, 0 }, +{ "fixup_arm_adr_pcrel_12", 1, 24, MCFixupKindInfo::FKF_IsPCRel }, +{ "fixup_arm_branch", 1, 24, MCFixupKindInfo::FKF_IsPCRel }, +{ "fixup_t2_condbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, +{ "fixup_t2_uncondbranch", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, +{ "fixup_arm_thumb_br", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, +{ "fixup_arm_thumb_bl", 0, 32, MCFixupKindInfo::FKF_IsPCRel }, +{ "fixup_arm_thumb_blx", 7, 21, MCFixupKindInfo::FKF_IsPCRel }, +{ "fixup_arm_thumb_cb", 0, 16, MCFixupKindInfo::FKF_IsPCRel }, +{ "fixup_arm_thumb_cp", 1, 8, MCFixupKindInfo::FKF_IsPCRel }, +{ "fixup_arm_thumb_bcc", 1, 8, MCFixupKindInfo::FKF_IsPCRel }, +{ "fixup_arm_movt_hi16", 0, 16, 0 }, +{ "fixup_arm_movw_lo16", 0, 16, 0 }, }; if (Kind < FirstTargetFixupKind) @@ -119,6 +123,12 @@ public: uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl &Fixups) const; + /// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit + /// immediate Thumb2 direct branch target. + uint32_t getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl &Fixups) const; + + /// getAdrLabelOpValue - Return encoding info for 12-bit immediate /// ADR label target. uint32_t getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, @@ -129,6 +139,10 @@ public: uint32_t getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl &Fixups) const; + /// getTAddrModeRegRegOpValue - Return encoding for 'reg + reg' operand. + uint32_t getTAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl &Fixups) const; + /// getT2AddrModeImm8s4OpValue - Return encoding info for 'reg +/- imm8<<2' /// operand. uint32_t getT2AddrModeImm8s4OpValue(const MCInst &MI, unsigned OpIdx, @@ -223,7 +237,7 @@ public: Binary |= ARM_AM::getSOImmValImm((unsigned)SoImmVal); return Binary; } - + /// getT2SOImmOpValue - Return an encoded 12-bit shifted-immediate value. unsigned getT2SOImmOpValue(const MCInst &MI, unsigned Op, SmallVectorImpl &Fixups) const { @@ -314,14 +328,14 @@ MCCodeEmitter *llvm::createARMMCCodeEmitter(const Target &, TargetMachine &TM, return new ARMMCCodeEmitter(TM, Ctx); } -/// NEONThumb2DataIPostEncoder - Post-process encoded NEON data-processing -/// instructions, and rewrite them to their Thumb2 form if we are currently in +/// NEONThumb2DataIPostEncoder - Post-process encoded NEON data-processing +/// instructions, and rewrite them to their Thumb2 form if we are currently in /// Thumb2 mode. unsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI, unsigned EncodedValue) const { const ARMSubtarget &Subtarget = TM.getSubtarget(); if (Subtarget.isThumb2()) { - // NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved + // NEON Thumb2 data-processsing encodings are very simple: bit 24 is moved // to bit 12 of the high half-word (i.e. bit 28), and bits 27-24 are // set to 1111. unsigned Bit24 = EncodedValue & 0x01000000; @@ -330,12 +344,12 @@ unsigned ARMMCCodeEmitter::NEONThumb2DataIPostEncoder(const MCInst &MI, EncodedValue |= Bit28; EncodedValue |= 0x0F000000; } - + return EncodedValue; } /// NEONThumb2LoadStorePostEncoder - Post-process encoded NEON load/store -/// instructions, and rewrite them to their Thumb2 form if we are currently in +/// instructions, and rewrite them to their Thumb2 form if we are currently in /// Thumb2 mode. unsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI, unsigned EncodedValue) const { @@ -344,12 +358,12 @@ unsigned ARMMCCodeEmitter::NEONThumb2LoadStorePostEncoder(const MCInst &MI, EncodedValue &= 0xF0FFFFFF; EncodedValue |= 0x09000000; } - + return EncodedValue; } /// NEONThumb2DupPostEncoder - Post-process encoded NEON vdup -/// instructions, and rewrite them to their Thumb2 form if we are currently in +/// instructions, and rewrite them to their Thumb2 form if we are currently in /// Thumb2 mode. unsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI, unsigned EncodedValue) const { @@ -358,7 +372,7 @@ unsigned ARMMCCodeEmitter::NEONThumb2DupPostEncoder(const MCInst &MI, EncodedValue &= 0x00FFFFFF; EncodedValue |= 0xEE000000; } - + return EncodedValue; } @@ -488,12 +502,38 @@ getThumbCBTargetOpValue(const MCInst &MI, unsigned OpIdx, uint32_t ARMMCCodeEmitter:: getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl &Fixups) const { + // FIXME: This really, really shouldn't use TargetMachine. We don't want + // coupling between MC and TM anywhere we can help it. const ARMSubtarget &Subtarget = TM.getSubtarget(); if (Subtarget.isThumb2()) - return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_branch, Fixups); + return + ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_condbranch, Fixups); return ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_arm_branch, Fixups); } +/// getUnconditionalBranchTargetOpValue - Return encoding info for 24-bit +/// immediate branch target. +uint32_t ARMMCCodeEmitter:: +getUnconditionalBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl &Fixups) const { + unsigned Val = + ::getBranchTargetOpValue(MI, OpIdx, ARM::fixup_t2_uncondbranch, Fixups); + bool I = (Val & 0x800000); + bool J1 = (Val & 0x400000); + bool J2 = (Val & 0x200000); + if (I ^ J1) + Val &= ~0x400000; + else + Val |= 0x400000; + + if (I ^ J2) + Val &= ~0x200000; + else + Val |= 0x200000; + + return Val; +} + /// getAdrLabelOpValue - Return encoding info for 12-bit immediate ADR label /// target. uint32_t ARMMCCodeEmitter:: @@ -504,6 +544,17 @@ getAdrLabelOpValue(const MCInst &MI, unsigned OpIdx, Fixups); } +/// getTAddrModeRegRegOpValue - Return encoding info for 'reg + reg' operand. +uint32_t ARMMCCodeEmitter:: +getTAddrModeRegRegOpValue(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl &Fixups) const { + const MCOperand &MO1 = MI.getOperand(OpIdx); + const MCOperand &MO2 = MI.getOperand(OpIdx+1); + unsigned Rn = getARMRegisterNumbering(MO1.getReg()); + unsigned Rm = getARMRegisterNumbering(MO2.getReg()); + return (Rm << 3) | Rn; +} + /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12' operand. uint32_t ARMMCCodeEmitter:: getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx, @@ -526,7 +577,7 @@ getAddrModeImm12OpValue(const MCInst &MI, unsigned OpIdx, Expr = MO.getExpr(); else Expr = MO2.getExpr(); - + const ARMSubtarget &Subtarget = TM.getSubtarget(); MCFixupKind Kind; if (Subtarget.isThumb2()) @@ -586,10 +637,10 @@ getMovtImmOpValue(const MCInst &MI, unsigned OpIdx, SmallVectorImpl &Fixups) const { // {20-16} = imm{15-12} // {11-0} = imm{11-0} - const MCOperand &MO = MI.getOperand(OpIdx); + const MCOperand &MO = MI.getOperand(OpIdx); if (MO.isImm()) { return static_cast(MO.getImm()); - } else if (const MCSymbolRefExpr *Expr = + } else if (const MCSymbolRefExpr *Expr = dyn_cast(MO.getExpr())) { MCFixupKind Kind; switch (Expr->getKind()) { @@ -878,8 +929,8 @@ getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum, SmallVectorImpl &Fixups) const { const MCOperand &MO1 = MI.getOperand(OpNum); const MCOperand &MO2 = MI.getOperand(OpNum+1); - const MCOperand &MO3 = MI.getOperand(OpNum+2); - + const MCOperand &MO3 = MI.getOperand(OpNum+2); + // Encoded as [Rn, Rm, imm]. // FIXME: Needs fixup support. unsigned Value = getARMRegisterNumbering(MO1.getReg()); @@ -887,7 +938,7 @@ getT2AddrModeSORegOpValue(const MCInst &MI, unsigned OpNum, Value |= getARMRegisterNumbering(MO2.getReg()); Value <<= 2; Value |= MO3.getImm(); - + return Value; } @@ -899,7 +950,7 @@ getT2AddrModeImm8OpValue(const MCInst &MI, unsigned OpNum, // FIXME: Needs fixup support. unsigned Value = getARMRegisterNumbering(MO1.getReg()); - + // Even though the immediate is 8 bits long, we need 9 bits in order // to represent the (inverse of the) sign bit. Value <<= 9;