Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(173)

Unified Diff: src/IceAssemblerARM32.h

Issue 1397933002: Start incorporating the ARM integrated assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Clean up code. Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/IceAssemblerARM32.h
diff --git a/src/IceAssemblerARM32.h b/src/IceAssemblerARM32.h
index 2a42826df60df8a77d83bd45db72a1202445e95e..6e2ea3d3b9f97af28b788dbc10ded90db1f04166 100644
--- a/src/IceAssemblerARM32.h
+++ b/src/IceAssemblerARM32.h
@@ -24,8 +24,11 @@
#define SUBZERO_SRC_ICEASSEMBLERARM32_H
#include "IceAssembler.h"
+#include "IceConditionCodesARM32.h"
#include "IceDefs.h"
#include "IceFixups.h"
+#include "IceRegistersARM32.h"
+#include "IceTargetLowering.h"
namespace Ice {
namespace ARM32 {
@@ -35,15 +38,24 @@ class AssemblerARM32 : public Assembler {
AssemblerARM32 &operator=(const AssemblerARM32 &) = delete;
public:
- explicit AssemblerARM32(bool use_far_branches = false)
- : Assembler(Asm_ARM32) {
- // This mode is only needed and implemented for MIPS and ARM.
- assert(!use_far_branches);
+ explicit AssemblerARM32(GlobalContext *Ctx, bool use_far_branches = false)
John 2015/10/09 12:12:24 two argument ctor -- explicit is no longer needed.
Karl 2015/10/09 19:08:18 Leaving as is, since C++ 11 will otherwise try imp
+ : Assembler(Asm_ARM32, Ctx) {
+ // TODO(kschimpf): Add mode if needed when branches are handled.
(void)use_far_branches;
}
~AssemblerARM32() override = default;
- void alignFunction() override { llvm_unreachable("Not yet implemented."); }
+ void alignFunction() override {
+ const SizeT Align = 1 << getBundleAlignLog2Bytes();
+ SizeT BytesNeeded = Utils::OffsetToAlignment(Buffer.getPosition(), Align);
+ constexpr SizeT InstSize = sizeof(int32_t);
+ assert(BytesNeeded % InstSize == 0);
+ while (BytesNeeded > 0) {
+ // TODO(kschimpf) Should this be NOP or some other instruction?
+ bkpt(0);
+ BytesNeeded -= InstSize;
+ }
+ }
SizeT getBundleAlignLog2Bytes() const override { return 4; }
@@ -67,18 +79,162 @@ public:
}
void bindCfgNodeLabel(SizeT NodeNumber) override {
- (void)NodeNumber;
- llvm_unreachable("Not yet implemented.");
+ assert(!getPreliminary());
+ Label *L = getOrCreateCfgNodeLabel(NodeNumber);
+ this->bind(L);
}
bool fixupIsPCRel(FixupKind Kind) const override {
(void)Kind;
llvm_unreachable("Not yet implemented.");
}
+ void bind(Label *label);
+
+ void bkpt(uint16_t imm16);
+
+ void bx(RegARM32::GPRRegister rm, CondARM32::Cond cond = CondARM32::AL);
static bool classof(const Assembler *Asm) {
return Asm->getKind() == Asm_ARM32;
}
+
+private:
+ // Instruction encoding bits.
+ enum {
John 2015/10/09 12:12:24 this trick for introducing class-level constants i
Karl 2015/10/09 19:08:18 Done.
+ H = 1 << 5, // halfword (or byte)
+ L = 1 << 20, // load (or store)
+ S = 1 << 20, // set condition code (or leave unchanged)
+ W = 1 << 21, // writeback base register (or leave unchanged)
+ A = 1 << 21, // accumulate in multiply instruction (or not)
+ B = 1 << 22, // unsigned byte (or word)
+ D = 1 << 22, // high/lo bit of start of s/d register range
+ N = 1 << 22, // long (or short)
+ U = 1 << 23, // positive (or negative) offset/index
+ P = 1 << 24, // offset/pre-indexed addressing (or post-indexed addressing)
+ I = 1 << 25, // immediate shifter operand (or not)
+
+ B0 = 1,
+ B1 = 1 << 1,
+ B2 = 1 << 2,
+ B3 = 1 << 3,
+ B4 = 1 << 4,
+ B5 = 1 << 5,
+ B6 = 1 << 6,
+ B7 = 1 << 7,
+ B8 = 1 << 8,
+ B9 = 1 << 9,
+ B10 = 1 << 10,
+ B11 = 1 << 11,
+ B12 = 1 << 12,
+ B16 = 1 << 16,
+ B17 = 1 << 17,
+ B18 = 1 << 18,
+ B19 = 1 << 19,
+ B20 = 1 << 20,
+ B21 = 1 << 21,
+ B22 = 1 << 22,
+ B23 = 1 << 23,
+ B24 = 1 << 24,
+ B25 = 1 << 25,
+ B26 = 1 << 26,
+ B27 = 1 << 27,
+ };
+
+ // Constants used for the decoding or encoding of the individual fields of
+ // instructions. Based on the "Figure 3-1 ARM instruction set summary".
Jim Stichnoth 2015/10/08 23:50:41 Figure 3-1 of what document?
Karl 2015/10/09 19:08:18 I agree that this comment is useless (I copied it
+ enum InstructionFields {
+ kConditionShift = 28,
John 2015/10/09 12:12:24 This is also just introducing class-level constant
Karl 2015/10/09 19:08:18 Done.
+ kConditionBits = 4,
+ kTypeShift = 25,
+ kTypeBits = 3,
+ kLinkShift = 24,
+ kLinkBits = 1,
+ kUShift = 23,
+ kUBits = 1,
+ kOpcodeShift = 21,
+ kOpcodeBits = 4,
+ kSShift = 20,
+ kSBits = 1,
+ kRnShift = 16,
+ kRnBits = 4,
+ kRdShift = 12,
+ kRdBits = 4,
+ kRsShift = 8,
+ kRsBits = 4,
+ kRmShift = 0,
+ kRmBits = 4,
+
+ // Immediate instruction fields encoding.
+ kRotateShift = 8,
+ kRotateBits = 4,
+ kImmed8Shift = 0,
+ kImmed8Bits = 8,
+
+ // Shift instruction register fields encodings.
+ kShiftImmShift = 7,
+ kShiftRegisterShift = 8,
+ kShiftImmBits = 5,
+ kShiftShift = 5,
+ kShiftBits = 2,
+
+ // Load/store instruction offset field encoding.
+ kOffset12Shift = 0,
+ kOffset12Bits = 12,
+ kOffset12Mask = 0x00000fff,
+
+ // Mul instruction register field encodings.
+ kMulRdShift = 16,
+ kMulRdBits = 4,
+ kMulRnShift = 12,
+ kMulRnBits = 4,
+
+ // Div instruction register field encodings.
+ kDivRdShift = 16,
+ kDivRdBits = 4,
+ kDivRmShift = 8,
+ kDivRmBints = 4,
+ kDivRnShift = 0,
+ kDivRnBits = 4,
+
+ // ldrex/strex register field encodings.
+ kLdExRnShift = 16,
+ kLdExRtShift = 12,
+ kStrExRnShift = 16,
+ kStrExRdShift = 12,
+ kStrExRtShift = 0,
+
+ // MRC instruction offset field encoding.
+ kCRmShift = 0,
+ kCRmBits = 4,
+ kOpc2Shift = 5,
+ kOpc2Bits = 3,
+ kCoprocShift = 8,
+ kCoprocBits = 4,
+ kCRnShift = 16,
+ kCRnBits = 4,
+ kOpc1Shift = 21,
+ kOpc1Bits = 3,
+
+ kBranchOffsetMask = 0x00ffffff
+ };
+
+ // A vector of pool-allocated x86 labels for CFG nodes.
+ using LabelVector = std::vector<Label *>;
+ LabelVector CfgNodeLabels;
+
+ Label *getOrCreateLabel(SizeT Number, LabelVector &Labels);
+ Label *getOrCreateCfgNodeLabel(SizeT NodeNumber) {
+ return getOrCreateLabel(NodeNumber, CfgNodeLabels);
+ }
+
+ void emitInt32(int32_t Value) { Buffer.emit<int32_t>(Value); }
+
+ static int32_t BkptEncoding(uint16_t imm16) {
+ // bkpt requires that the cond field is AL.
+ // cccc00010010iiiiiiiiiiii0111iiii where cccc=AL and i in imm16
+ return (CondARM32::AL << kConditionShift) | B24 | B21 |
+ ((imm16 >> 4) << 8) | B6 | B5 | B4 | (imm16 & 0xf);
+ }
};
} // end of namespace ARM32

Powered by Google App Engine
This is Rietveld 408576698