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

Side by Side Diff: src/IceAssemblerARM32.cpp

Issue 1459673003: Add recognizing register-shifted forms in ARM assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix nits to resolve conflicts with master. 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
« no previous file with comments | « no previous file | tests_lit/assembler/arm32/cmp.ll » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceAssemblerARM32.cpp - Assembler for ARM32 --*- C++ -*-===// 1 //===- subzero/src/IceAssemblerARM32.cpp - 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 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 // Rn should be used, and iiiiiiiiiiii defines the rotated Imm8 value. 192 // Rn should be used, and iiiiiiiiiiii defines the rotated Imm8 value.
193 DecodedAsImmRegOffset, 193 DecodedAsImmRegOffset,
194 // Value=0000000pu0w00nnnnttttiiiiiss0mmmm where nnnn is the base register Rn, 194 // Value=0000000pu0w00nnnnttttiiiiiss0mmmm where nnnn is the base register Rn,
195 // mmmm is the index register Rm, iiiii is the shift amount, ss is the shift 195 // mmmm is the index register Rm, iiiii is the shift amount, ss is the shift
196 // kind, p=1 if pre-indexed addressing, u=1 if offset positive, and w=1 if 196 // kind, p=1 if pre-indexed addressing, u=1 if offset positive, and w=1 if
197 // writeback to Rn. 197 // writeback to Rn.
198 DecodedAsShiftRotateImm5, 198 DecodedAsShiftRotateImm5,
199 // Value=000000000000000000000iiiii0000000 iiii defines the Imm5 value to 199 // Value=000000000000000000000iiiii0000000 iiii defines the Imm5 value to
200 // shift. 200 // shift.
201 DecodedAsShiftImm5, 201 DecodedAsShiftImm5,
202 // i.e. iiiiiss0mmmm where mmmm is the register to rotate, ss is the shift
203 // kind, and iiiii is the shift amount.
204 DecodedAsShiftedRegister,
202 // Value is 32bit integer constant. 205 // Value is 32bit integer constant.
203 DecodedAsConstI32 206 DecodedAsConstI32
204 }; 207 };
205 208
206 // Sets Encoding to a rotated Imm8 encoding of Value, if possible. 209 // Sets Encoding to a rotated Imm8 encoding of Value, if possible.
207 inline IValueT encodeRotatedImm8(IValueT RotateAmt, IValueT Immed8) { 210 inline IValueT encodeRotatedImm8(IValueT RotateAmt, IValueT Immed8) {
208 assert(RotateAmt < (1 << kRotateBits)); 211 assert(RotateAmt < (1 << kRotateBits));
209 assert(Immed8 < (1 << kImmed8Bits)); 212 assert(Immed8 < (1 << kImmed8Bits));
210 return (RotateAmt << kRotateShift) | (Immed8 << kImmed8Shift); 213 return (RotateAmt << kRotateShift) | (Immed8 << kImmed8Shift);
211 } 214 }
212 215
213 // Encodes iiiiitt0mmmm for data-processing (2nd) operands where iiiii=Imm5, 216 // Encodes iiiiitt0mmmm for data-processing (2nd) operands where iiiii=Imm5,
214 // tt=Shift, and mmmm=Rm. 217 // tt=Shift, and mmmm=Rm.
215 IValueT encodeShiftRotateImm5(IValueT Rm, OperandARM32::ShiftKind Shift, 218 IValueT encodeShiftRotateImm5(IValueT Rm, OperandARM32::ShiftKind Shift,
216 IOffsetT imm5) { 219 IOffsetT imm5) {
217 (void)kShiftImmBits; 220 (void)kShiftImmBits;
218 assert(imm5 < (1 << kShiftImmBits)); 221 assert(imm5 < (1 << kShiftImmBits));
219 return (imm5 << kShiftImmShift) | (encodeShift(Shift) << kShiftShift) | Rm; 222 return (imm5 << kShiftImmShift) | (encodeShift(Shift) << kShiftShift) | Rm;
220 } 223 }
221 224
222 // Encodes mmmmtt01ssss for data-processing operands where mmmm=Rm, ssss=Rs, and 225 // Encodes mmmmtt01ssss for data-processing operands where mmmm=Rm, ssss=Rs, and
223 // tt=Shift. 226 // tt=Shift.
224 IValueT encodeShiftRotateReg(IValueT Rm, OperandARM32::ShiftKind Shift, 227 IValueT encodeShiftRotateReg(IValueT Rm, OperandARM32::ShiftKind Shift,
225 IValueT Rs) { 228 IValueT Rs) {
226 return (Rs << kRsShift) | (encodeShift(Shift) << kShiftShift) | B4 | 229 return (Rs << kRsShift) | (encodeShift(Shift) << kShiftShift) | B4 |
227 (Rm << kRmShift); 230 (Rm << kRmShift);
228 } 231 }
229 232
230 DecodedResult decodeOperand(const Operand *Opnd, IValueT &Value) { 233 DecodedResult decodeOperand(const Operand *Opnd, IValueT &Value) {
234 Value = 0; // Make sure initialized.
231 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { 235 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) {
232 if (Var->hasReg()) { 236 if (Var->hasReg()) {
233 Value = Var->getRegNum(); 237 Value = Var->getRegNum();
234 return DecodedAsRegister; 238 return DecodedAsRegister;
235 } 239 }
236 return CantDecode; 240 return CantDecode;
237 } 241 }
238 if (const auto *FlexImm = llvm::dyn_cast<OperandARM32FlexImm>(Opnd)) { 242 if (const auto *FlexImm = llvm::dyn_cast<OperandARM32FlexImm>(Opnd)) {
239 const IValueT Immed8 = FlexImm->getImm(); 243 const IValueT Immed8 = FlexImm->getImm();
240 const IValueT Rotate = FlexImm->getRotateAmt(); 244 const IValueT Rotate = FlexImm->getRotateAmt();
241 if (!((Rotate < (1 << kRotateBits)) && (Immed8 < (1 << kImmed8Bits)))) 245 if (!((Rotate < (1 << kRotateBits)) && (Immed8 < (1 << kImmed8Bits))))
242 return CantDecode; 246 return CantDecode;
243 Value = (Rotate << kRotateShift) | (Immed8 << kImmed8Shift); 247 Value = (Rotate << kRotateShift) | (Immed8 << kImmed8Shift);
244 return DecodedAsRotatedImm8; 248 return DecodedAsRotatedImm8;
245 } 249 }
246 if (const auto *Const = llvm::dyn_cast<ConstantInteger32>(Opnd)) { 250 if (const auto *Const = llvm::dyn_cast<ConstantInteger32>(Opnd)) {
247 Value = Const->getValue(); 251 Value = Const->getValue();
248 return DecodedAsConstI32; 252 return DecodedAsConstI32;
249 } 253 }
254 if (const auto *FlexReg = llvm::dyn_cast<OperandARM32FlexReg>(Opnd)) {
255 Operand *Amt = FlexReg->getShiftAmt();
256 if (const auto *Imm5 = llvm::dyn_cast<OperandARM32ShAmtImm>(Amt)) {
257 IValueT Rm;
258 if (decodeOperand(FlexReg->getReg(), Rm) != DecodedAsRegister)
259 return CantDecode;
260 Value =
261 encodeShiftRotateImm5(Rm, FlexReg->getShiftOp(), Imm5->getShAmtImm());
262 return DecodedAsShiftedRegister;
263 }
264 // TODO(kschimpf): Handle case where Amt is a register?
265 }
250 if (const auto *ShImm = llvm::dyn_cast<OperandARM32ShAmtImm>(Opnd)) { 266 if (const auto *ShImm = llvm::dyn_cast<OperandARM32ShAmtImm>(Opnd)) {
251 const IValueT Immed5 = ShImm->getShAmtImm(); 267 const IValueT Immed5 = ShImm->getShAmtImm();
252 assert(Immed5 < (1 << kShiftImmBits)); 268 assert(Immed5 < (1 << kShiftImmBits));
253 Value = (Immed5 << kShiftImmShift); 269 Value = (Immed5 << kShiftImmShift);
254 return DecodedAsShiftImm5; 270 return DecodedAsShiftImm5;
255 } 271 }
256 return CantDecode; 272 return CantDecode;
257 } 273 }
258 274
259 IValueT decodeImmRegOffset(RegARM32::GPRRegister Reg, IOffsetT Offset, 275 IValueT decodeImmRegOffset(RegARM32::GPRRegister Reg, IOffsetT Offset,
260 OperandARM32Mem::AddrMode Mode) { 276 OperandARM32Mem::AddrMode Mode) {
261 IValueT Value = Mode | (encodeGPRRegister(Reg) << kRnShift); 277 IValueT Value = Mode | (encodeGPRRegister(Reg) << kRnShift);
262 if (Offset < 0) { 278 if (Offset < 0) {
263 Value = (Value ^ U) | -Offset; // Flip U to adjust sign. 279 Value = (Value ^ U) | -Offset; // Flip U to adjust sign.
264 } else { 280 } else {
265 Value |= Offset; 281 Value |= Offset;
266 } 282 }
267 return Value; 283 return Value;
268 } 284 }
269 285
270 // Decodes memory address Opnd, and encodes that information into Value, 286 // Decodes memory address Opnd, and encodes that information into Value,
271 // based on how ARM represents the address. Returns how the value was encoded. 287 // based on how ARM represents the address. Returns how the value was encoded.
272 DecodedResult decodeAddress(const Operand *Opnd, IValueT &Value, 288 DecodedResult decodeAddress(const Operand *Opnd, IValueT &Value,
273 const AssemblerARM32::TargetInfo &TInfo) { 289 const AssemblerARM32::TargetInfo &TInfo) {
290 Value = 0; // Make sure initialized.
274 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) { 291 if (const auto *Var = llvm::dyn_cast<Variable>(Opnd)) {
275 // Should be a stack variable, with an offset. 292 // Should be a stack variable, with an offset.
276 if (Var->hasReg()) 293 if (Var->hasReg())
277 return CantDecode; 294 return CantDecode;
278 IOffsetT Offset = Var->getStackOffset(); 295 IOffsetT Offset = Var->getStackOffset();
279 if (!Utils::IsAbsoluteUint(12, Offset)) 296 if (!Utils::IsAbsoluteUint(12, Offset))
280 return CantDecode; 297 return CantDecode;
281 int32_t BaseRegNum = Var->getBaseRegNum(); 298 int32_t BaseRegNum = Var->getBaseRegNum();
282 if (BaseRegNum == Variable::NoRegister) { 299 if (BaseRegNum == Variable::NoRegister) {
283 BaseRegNum = TInfo.FrameOrStackReg; 300 BaseRegNum = TInfo.FrameOrStackReg;
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 // xxx{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>} 510 // xxx{s}<c> <Rd>, <Rn>, <Rm>{, <shiff>}
494 // 511 //
495 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn, 512 // cccc0000100snnnnddddiiiiitt0mmmm where cccc=Cond, dddd=Rd, nnnn=Rn,
496 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags. 513 // mmmm=Rm, iiiii=Shift, tt=ShiftKind, and s=SetFlags.
497 constexpr IValueT Imm5 = 0; 514 constexpr IValueT Imm5 = 0;
498 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Imm5); 515 Src1Value = encodeShiftRotateImm5(Src1Value, OperandARM32::kNoShift, Imm5);
499 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value, 516 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value,
500 RuleChecks); 517 RuleChecks);
501 return; 518 return;
502 } 519 }
520 case DecodedAsShiftedRegister: {
521 // Form is defined in case DecodedAsRegister. (i.e. XXX (register)).
522 emitType01(Cond, kInstTypeDataRegister, Opcode, SetFlags, Rn, Rd, Src1Value,
523 RuleChecks);
524 return;
525 }
503 case DecodedAsConstI32: { 526 case DecodedAsConstI32: {
504 // See if we can convert this to an XXX (immediate). 527 // See if we can convert this to an XXX (immediate).
505 IValueT RotateAmt; 528 IValueT RotateAmt;
506 IValueT Imm8; 529 IValueT Imm8;
507 if (!OperandARM32FlexImm::canHoldImm(Src1Value, &RotateAmt, &Imm8)) 530 if (!OperandARM32FlexImm::canHoldImm(Src1Value, &RotateAmt, &Imm8))
508 return setNeedsTextFixup(); 531 return setNeedsTextFixup();
509 Src1Value = encodeRotatedImm8(RotateAmt, Imm8); 532 Src1Value = encodeRotatedImm8(RotateAmt, Imm8);
510 // Intentionally fall to next case! 533 // Intentionally fall to next case!
511 } 534 }
512 case DecodedAsRotatedImm8: { 535 case DecodedAsRotatedImm8: {
(...skipping 873 matching lines...) Expand 10 before | Expand all | Expand 10 after
1386 // rr defined (RotationValue) rotate. 1409 // rr defined (RotationValue) rotate.
1387 constexpr IValueT Opcode = B26 | B25 | B23 | B22 | B21 | B20; 1410 constexpr IValueT Opcode = B26 | B25 | B23 | B22 | B21 | B20;
1388 emitUxt(Cond, Opcode, Rd, Rn, Rm, Rotation); 1411 emitUxt(Cond, Opcode, Rd, Rn, Rm, Rotation);
1389 return; 1412 return;
1390 } 1413 }
1391 } 1414 }
1392 } 1415 }
1393 1416
1394 } // end of namespace ARM32 1417 } // end of namespace ARM32
1395 } // end of namespace Ice 1418 } // end of namespace Ice
OLDNEW
« no previous file with comments | « no previous file | tests_lit/assembler/arm32/cmp.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698