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

Side by Side Diff: src/IceAssemblerARM32.h

Issue 1418313003: Handle branch relative to pc in ARM integrated assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nits. Created 5 years, 1 month 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 unified diff | Download patch
OLDNEW
1 //===- subzero/src/IceAssemblerARM32.h - Assembler for ARM32 ----*- C++ -*-===// 1 //===- subzero/src/IceAssemblerARM32.h - Assembler for ARM32 ----*- C++ -*-===//
2 // 2 //
3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
4 // for details. All rights reserved. Use of this source code is governed by a 4 // for details. All rights reserved. Use of this source code is governed by a
5 // BSD-style license that can be found in the LICENSE file. 5 // BSD-style license that can be found in the LICENSE file.
6 // 6 //
7 // Modified by the Subzero authors. 7 // Modified by the Subzero authors.
8 // 8 //
9 //===----------------------------------------------------------------------===// 9 //===----------------------------------------------------------------------===//
10 // 10 //
(...skipping 20 matching lines...) Expand all
31 #include "IceConditionCodesARM32.h" 31 #include "IceConditionCodesARM32.h"
32 #include "IceDefs.h" 32 #include "IceDefs.h"
33 #include "IceFixups.h" 33 #include "IceFixups.h"
34 #include "IceInstARM32.h" 34 #include "IceInstARM32.h"
35 #include "IceRegistersARM32.h" 35 #include "IceRegistersARM32.h"
36 #include "IceTargetLowering.h" 36 #include "IceTargetLowering.h"
37 37
38 namespace Ice { 38 namespace Ice {
39 namespace ARM32 { 39 namespace ARM32 {
40 40
41 /// Encoding of an ARM 32-bit instruction.
42 using InstValueType = uint32_t;
Jim Stichnoth 2015/10/23 21:32:07 You might consider shortening these to InstValueT
Karl 2015/10/26 18:32:43 ValueT appeared too easy to confuse with other pos
43
44 /// An Offset value (+/-) used in an ARM 32-bit instruction.
45 using InstOffsetType = int32_t;
46
41 class AssemblerARM32 : public Assembler { 47 class AssemblerARM32 : public Assembler {
42 AssemblerARM32() = delete; 48 AssemblerARM32() = delete;
43 AssemblerARM32(const AssemblerARM32 &) = delete; 49 AssemblerARM32(const AssemblerARM32 &) = delete;
44 AssemblerARM32 &operator=(const AssemblerARM32 &) = delete; 50 AssemblerARM32 &operator=(const AssemblerARM32 &) = delete;
45 51
46 public: 52 public:
47 explicit AssemblerARM32(GlobalContext *Ctx, bool use_far_branches = false) 53 explicit AssemblerARM32(GlobalContext *Ctx, bool use_far_branches = false)
48 : Assembler(Asm_ARM32, Ctx) { 54 : Assembler(Asm_ARM32, Ctx) {
49 // TODO(kschimpf): Add mode if needed when branches are handled. 55 // TODO(kschimpf): Add mode if needed when branches are handled.
50 (void)use_far_branches; 56 (void)use_far_branches;
51 } 57 }
52 ~AssemblerARM32() override { 58 ~AssemblerARM32() override {
53 if (BuildDefs::asserts()) { 59 if (BuildDefs::asserts()) {
54 for (const Label *Label : CfgNodeLabels) { 60 for (const Label *Label : CfgNodeLabels) {
55 Label->finalCheck(); 61 Label->finalCheck();
56 } 62 }
57 for (const Label *Label : LocalLabels) { 63 for (const Label *Label : LocalLabels) {
58 Label->finalCheck(); 64 Label->finalCheck();
59 } 65 }
60 } 66 }
61 } 67 }
62 68
63 void alignFunction() override { 69 void alignFunction() override {
64 const SizeT Align = 1 << getBundleAlignLog2Bytes(); 70 const SizeT Align = 1 << getBundleAlignLog2Bytes();
65 SizeT BytesNeeded = Utils::OffsetToAlignment(Buffer.getPosition(), Align); 71 SizeT BytesNeeded = Utils::OffsetToAlignment(Buffer.getPosition(), Align);
66 constexpr uint32_t UndefinedInst = 0xe7fedef0; // udf #60896 72 constexpr InstValueType UndefinedInst = 0xe7fedef0; // udf #60896
67 constexpr SizeT InstSize = sizeof(int32_t); 73 constexpr SizeT InstSize = sizeof(InstValueType);
68 assert(BytesNeeded % InstSize == 0); 74 assert(BytesNeeded % InstSize == 0);
69 while (BytesNeeded > 0) { 75 while (BytesNeeded > 0) {
70 AssemblerBuffer::EnsureCapacity ensured(&Buffer); 76 AssemblerBuffer::EnsureCapacity ensured(&Buffer);
71 emitInst(UndefinedInst); 77 emitInst(UndefinedInst);
72 BytesNeeded -= InstSize; 78 BytesNeeded -= InstSize;
73 } 79 }
74 } 80 }
75 81
76 SizeT getBundleAlignLog2Bytes() const override { return 4; } 82 SizeT getBundleAlignLog2Bytes() const override { return 4; }
77 83
78 const char *getAlignDirective() const override { return ".p2alignl"; } 84 const char *getAlignDirective() const override { return ".p2alignl"; }
79 85
80 llvm::ArrayRef<uint8_t> getNonExecBundlePadding() const override { 86 llvm::ArrayRef<uint8_t> getNonExecBundlePadding() const override {
81 // Use a particular UDF encoding -- TRAPNaCl in LLVM: 0xE7FEDEF0 87 // Use a particular UDF encoding -- TRAPNaCl in LLVM: 0xE7FEDEF0
82 // http://llvm.org/viewvc/llvm-project?view=revision&revision=173943 88 // http://llvm.org/viewvc/llvm-project?view=revision&revision=173943
83 static const uint8_t Padding[] = {0xE7, 0xFE, 0xDE, 0xF0}; 89 static const uint8_t Padding[] = {0xE7, 0xFE, 0xDE, 0xF0};
84 return llvm::ArrayRef<uint8_t>(Padding, 4); 90 return llvm::ArrayRef<uint8_t>(Padding, 4);
85 } 91 }
86 92
87 void padWithNop(intptr_t Padding) override { 93 void padWithNop(intptr_t Padding) override {
88 (void)Padding; 94 (void)Padding;
89 llvm_unreachable("Not yet implemented."); 95 llvm_unreachable("Not yet implemented.");
90 } 96 }
91 97
92 Ice::Label *getCfgNodeLabel(SizeT NodeNumber) override { 98 Ice::Label *getCfgNodeLabel(SizeT NodeNumber) override {
93 assert(NodeNumber < CfgNodeLabels.size()); 99 assert(NodeNumber < CfgNodeLabels.size());
94 return CfgNodeLabels[NodeNumber]; 100 return CfgNodeLabels[NodeNumber];
95 } 101 }
96 102
97 void bindCfgNodeLabel(const CfgNode *Node) override; 103 Label *getOrCreateCfgNodeLabel(SizeT NodeNumber) {
104 return getOrCreateLabel(NodeNumber, CfgNodeLabels);
105 }
106
107 Label *getOrCreateLocalLabel(SizeT Number) {
108 return getOrCreateLabel(Number, LocalLabels);
109 }
98 110
99 void bindLocalLabel(SizeT Number) { 111 void bindLocalLabel(SizeT Number) {
100 Label *L = getOrCreateLocalLabel(Number); 112 Label *L = getOrCreateLocalLabel(Number);
101 if (!getPreliminary()) 113 if (!getPreliminary())
102 this->bind(L); 114 this->bind(L);
103 } 115 }
104 116
105 bool fixupIsPCRel(FixupKind Kind) const override { 117 bool fixupIsPCRel(FixupKind Kind) const override {
106 (void)Kind; 118 (void)Kind;
107 // TODO(kschimpf) Decide if we need this. 119 // TODO(kschimpf) Decide if we need this.
108 return false; 120 return false;
109 } 121 }
110 122
111 void bind(Label *label); 123 void bind(Label *label);
112 124
113 // List of instructions implemented by integrated assembler. 125 // List of instructions implemented by integrated assembler.
114 126
115 void add(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1, 127 void add(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
116 bool SetFlags, CondARM32::Cond Cond); 128 bool SetFlags, CondARM32::Cond Cond);
117 129
130 void b(Label *L, CondARM32::Cond Cond);
131
118 void bkpt(uint16_t Imm16); 132 void bkpt(uint16_t Imm16);
119 133
120 void ldr(const Operand *OpRt, const Operand *OpAddress, CondARM32::Cond Cond); 134 void ldr(const Operand *OpRt, const Operand *OpAddress, CondARM32::Cond Cond);
121 135
122 void mov(const Operand *OpRd, const Operand *OpSrc, CondARM32::Cond Cond); 136 void mov(const Operand *OpRd, const Operand *OpSrc, CondARM32::Cond Cond);
123 137
124 void bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond = CondARM32::AL); 138 void bx(RegARM32::GPRRegister Rm, CondARM32::Cond Cond = CondARM32::AL);
125 139
126 void str(const Operand *OpRt, const Operand *OpAddress, CondARM32::Cond Cond); 140 void str(const Operand *OpRt, const Operand *OpAddress, CondARM32::Cond Cond);
127 141
128 void sub(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1, 142 void sub(const Operand *OpRd, const Operand *OpRn, const Operand *OpSrc1,
129 bool SetFlags, CondARM32::Cond Cond); 143 bool SetFlags, CondARM32::Cond Cond);
130 144
131 static bool classof(const Assembler *Asm) { 145 static bool classof(const Assembler *Asm) {
132 return Asm->getKind() == Asm_ARM32; 146 return Asm->getKind() == Asm_ARM32;
133 } 147 }
134 148
135 void emitTextInst(const std::string &Text, SizeT InstSize = sizeof(uint32_t)); 149 void emitTextInst(const std::string &Text,
150 SizeT InstSize = sizeof(InstValueType));
136 151
137 private: 152 private:
138 // A vector of pool-allocated x86 labels for CFG nodes. 153 // A vector of pool-allocated x86 labels for CFG nodes.
139 using LabelVector = std::vector<Label *>; 154 using LabelVector = std::vector<Label *>;
140 LabelVector CfgNodeLabels; 155 LabelVector CfgNodeLabels;
141 // A vector of pool-allocated x86 labels for Local labels. 156 // A vector of pool-allocated x86 labels for Local labels.
142 LabelVector LocalLabels; 157 LabelVector LocalLabels;
143 158
144 Label *getOrCreateLabel(SizeT Number, LabelVector &Labels); 159 Label *getOrCreateLabel(SizeT Number, LabelVector &Labels);
145 Label *getOrCreateCfgNodeLabel(SizeT NodeNumber) {
146 return getOrCreateLabel(NodeNumber, CfgNodeLabels);
147 }
148 Label *getOrCreateLocalLabel(SizeT Number) {
149 return getOrCreateLabel(Number, LocalLabels);
150 }
151 160
152 void emitInst(uint32_t Value) { Buffer.emit<uint32_t>(Value); } 161 void bindCfgNodeLabel(const CfgNode *Node) override;
162
163 void emitInst(InstValueType Value) { Buffer.emit<InstValueType>(Value); }
153 164
154 // Pattern cccctttoooosnnnnddddiiiiiiiiiiii where cccc=Cond, ttt=Type, 165 // Pattern cccctttoooosnnnnddddiiiiiiiiiiii where cccc=Cond, ttt=Type,
155 // oooo=Opcode, nnnn=Rn, dddd=Rd, iiiiiiiiiiii=imm12 (See ARM section A5.2.3). 166 // oooo=Opcode, nnnn=Rn, dddd=Rd, iiiiiiiiiiii=imm12 (See ARM section A5.2.3).
156 void emitType01(CondARM32::Cond Cond, uint32_t Type, uint32_t Opcode, 167 void emitType01(CondARM32::Cond Cond, InstValueType Type,
157 bool SetCc, uint32_t Rn, uint32_t Rd, uint32_t imm12); 168 InstValueType Opcode, bool SetCc, InstValueType Rn,
169 InstValueType Rd, InstValueType imm12);
170
171 void emitType05(CondARM32::Cond COnd, int32_t Offset, bool Link);
158 172
159 // Pattern ccccoooaabalnnnnttttaaaaaaaaaaaa where cccc=Cond, ooo=InstType, 173 // Pattern ccccoooaabalnnnnttttaaaaaaaaaaaa where cccc=Cond, ooo=InstType,
160 // l=isLoad, b=isByte, and aaa0a0aaaa0000aaaaaaaaaaaa=Address. Note that 174 // l=isLoad, b=isByte, and aaa0a0aaaa0000aaaaaaaaaaaa=Address. Note that
161 // Address is assumed to be defined by decodeAddress() in 175 // Address is assumed to be defined by decodeAddress() in
162 // IceAssemblerARM32.cpp. 176 // IceAssemblerARM32.cpp.
163 void emitMemOp(CondARM32::Cond Cond, uint32_t InstType, bool IsLoad, 177 void emitMemOp(CondARM32::Cond Cond, InstValueType InstType, bool IsLoad,
164 bool IsByte, uint32_t Rt, uint32_t Address); 178 bool IsByte, uint32_t Rt, uint32_t Address);
179
180 void emitBranch(Label *L, CondARM32::Cond, bool Link);
181
182 // Encodes The given Offset into the branch instruction Inst.
183 InstValueType encodeBranchOffset(InstOffsetType Offset, InstValueType Inst);
184
185 // Returns the offset encoded in the branch instruction Inst.
186 static InstOffsetType decodeBranchOffset(InstValueType Inst);
165 }; 187 };
166 188
167 } // end of namespace ARM32 189 } // end of namespace ARM32
168 } // end of namespace Ice 190 } // end of namespace Ice
169 191
170 #endif // SUBZERO_SRC_ICEASSEMBLERARM32_H 192 #endif // SUBZERO_SRC_ICEASSEMBLERARM32_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698