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

Side by Side Diff: src/IceTargetLoweringARM32.h

Issue 1359193003: Subzero. Enables (most) crosstests for ARM32. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Addresses comments. 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 unified diff | Download patch
« no previous file with comments | « src/IceInstARM32.def ('k') | src/IceTargetLoweringARM32.cpp » ('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/IceTargetLoweringARM32.h - ARM32 lowering ----*- C++ -*-===// 1 //===- subzero/src/IceTargetLoweringARM32.h - ARM32 lowering ----*- C++ -*-===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 /// 9 ///
10 /// \file 10 /// \file
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 CondARM32::Cond); 182 CondARM32::Cond);
183 void lowerIDivRem(Variable *Dest, Variable *T, Variable *Src0R, Operand *Src1, 183 void lowerIDivRem(Variable *Dest, Variable *T, Variable *Src0R, Operand *Src1,
184 ExtInstr ExtFunc, DivInstr DivFunc, 184 ExtInstr ExtFunc, DivInstr DivFunc,
185 const char *DivHelperName, bool IsRemainder); 185 const char *DivHelperName, bool IsRemainder);
186 186
187 void lowerCLZ(Variable *Dest, Variable *ValLo, Variable *ValHi); 187 void lowerCLZ(Variable *Dest, Variable *ValLo, Variable *ValHi);
188 188
189 // The following are helpers that insert lowered ARM32 instructions with 189 // The following are helpers that insert lowered ARM32 instructions with
190 // minimal syntactic overhead, so that the lowering code can look as close to 190 // minimal syntactic overhead, so that the lowering code can look as close to
191 // assembly as practical. 191 // assembly as practical.
192
193 void _add(Variable *Dest, Variable *Src0, Operand *Src1, 192 void _add(Variable *Dest, Variable *Src0, Operand *Src1,
194 CondARM32::Cond Pred = CondARM32::AL) { 193 CondARM32::Cond Pred = CondARM32::AL) {
195 Context.insert(InstARM32Add::create(Func, Dest, Src0, Src1, Pred)); 194 Context.insert(InstARM32Add::create(Func, Dest, Src0, Src1, Pred));
196 } 195 }
197 void _adds(Variable *Dest, Variable *Src0, Operand *Src1, 196 void _adds(Variable *Dest, Variable *Src0, Operand *Src1,
198 CondARM32::Cond Pred = CondARM32::AL) { 197 CondARM32::Cond Pred = CondARM32::AL) {
199 constexpr bool SetFlags = true; 198 constexpr bool SetFlags = true;
200 Context.insert( 199 Context.insert(
201 InstARM32Add::create(Func, Dest, Src0, Src1, Pred, SetFlags)); 200 InstARM32Add::create(Func, Dest, Src0, Src1, Pred, SetFlags));
202 } 201 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 Context.insert(InstARM32Cmp::create(Func, Src0, Src1, Pred)); 238 Context.insert(InstARM32Cmp::create(Func, Src0, Src1, Pred));
240 } 239 }
241 void _clz(Variable *Dest, Variable *Src0, 240 void _clz(Variable *Dest, Variable *Src0,
242 CondARM32::Cond Pred = CondARM32::AL) { 241 CondARM32::Cond Pred = CondARM32::AL) {
243 Context.insert(InstARM32Clz::create(Func, Dest, Src0, Pred)); 242 Context.insert(InstARM32Clz::create(Func, Dest, Src0, Pred));
244 } 243 }
245 void _eor(Variable *Dest, Variable *Src0, Operand *Src1, 244 void _eor(Variable *Dest, Variable *Src0, Operand *Src1,
246 CondARM32::Cond Pred = CondARM32::AL) { 245 CondARM32::Cond Pred = CondARM32::AL) {
247 Context.insert(InstARM32Eor::create(Func, Dest, Src0, Src1, Pred)); 246 Context.insert(InstARM32Eor::create(Func, Dest, Src0, Src1, Pred));
248 } 247 }
248 /// _ldr, for all your memory to Variable data moves. It handles all types
249 /// (integer, floating point, and vectors.) Addr needs to be valid for Dest's
250 /// type (e.g., no immediates for vector loads, and no index registers for fp
251 /// loads.)
249 void _ldr(Variable *Dest, OperandARM32Mem *Addr, 252 void _ldr(Variable *Dest, OperandARM32Mem *Addr,
250 CondARM32::Cond Pred = CondARM32::AL) { 253 CondARM32::Cond Pred = CondARM32::AL) {
251 Context.insert(InstARM32Ldr::create(Func, Dest, Addr, Pred)); 254 Context.insert(InstARM32Ldr::create(Func, Dest, Addr, Pred));
252 } 255 }
253 void _lsl(Variable *Dest, Variable *Src0, Operand *Src1, 256 void _lsl(Variable *Dest, Variable *Src0, Operand *Src1,
254 CondARM32::Cond Pred = CondARM32::AL) { 257 CondARM32::Cond Pred = CondARM32::AL) {
255 Context.insert(InstARM32Lsl::create(Func, Dest, Src0, Src1, Pred)); 258 Context.insert(InstARM32Lsl::create(Func, Dest, Src0, Src1, Pred));
256 } 259 }
257 void _lsr(Variable *Dest, Variable *Src0, Operand *Src1, 260 void _lsr(Variable *Dest, Variable *Src0, Operand *Src1,
258 CondARM32::Cond Pred = CondARM32::AL) { 261 CondARM32::Cond Pred = CondARM32::AL) {
259 Context.insert(InstARM32Lsr::create(Func, Dest, Src0, Src1, Pred)); 262 Context.insert(InstARM32Lsr::create(Func, Dest, Src0, Src1, Pred));
260 } 263 }
261 void _mla(Variable *Dest, Variable *Src0, Variable *Src1, Variable *Acc, 264 void _mla(Variable *Dest, Variable *Src0, Variable *Src1, Variable *Acc,
262 CondARM32::Cond Pred = CondARM32::AL) { 265 CondARM32::Cond Pred = CondARM32::AL) {
263 Context.insert(InstARM32Mla::create(Func, Dest, Src0, Src1, Acc, Pred)); 266 Context.insert(InstARM32Mla::create(Func, Dest, Src0, Src1, Acc, Pred));
264 } 267 }
265 void _mls(Variable *Dest, Variable *Src0, Variable *Src1, Variable *Acc, 268 void _mls(Variable *Dest, Variable *Src0, Variable *Src1, Variable *Acc,
266 CondARM32::Cond Pred = CondARM32::AL) { 269 CondARM32::Cond Pred = CondARM32::AL) {
267 Context.insert(InstARM32Mls::create(Func, Dest, Src0, Src1, Acc, Pred)); 270 Context.insert(InstARM32Mls::create(Func, Dest, Src0, Src1, Acc, Pred));
268 } 271 }
269 /// If Dest=nullptr is passed in, then a new variable is created, marked as 272 /// _mov, for all your Variable to Variable data movement needs. It handles
270 /// infinite register allocation weight, and returned through the in/out Dest 273 /// all types (integer, floating point, and vectors), as well as moves between
271 /// argument. 274 /// Core and VFP registers. This is not a panacea: you must obey the (weird,
272 void _mov(Variable *&Dest, Operand *Src0, 275 /// confusing, non-uniform) rules for data moves in ARM.
273 CondARM32::Cond Pred = CondARM32::AL, 276 void _mov(Variable *Dest, Operand *Src0,
274 int32_t RegNum = Variable::NoRegister) { 277 CondARM32::Cond Pred = CondARM32::AL) {
275 if (Dest == nullptr) 278 // _mov used to be unique in the sense that it would create a temporary
276 Dest = makeReg(Src0->getType(), RegNum); 279 // automagically if Dest was nullptr. It won't do that anymore, so we keep
280 // an assert around just in case there is some untested code path where Dest
281 // is nullptr.
282 assert(Dest != nullptr);
277 Context.insert(InstARM32Mov::create(Func, Dest, Src0, Pred)); 283 Context.insert(InstARM32Mov::create(Func, Dest, Src0, Pred));
278 } 284 }
279 void _mov_nonkillable(Variable *Dest, Operand *Src0, 285 void _mov_nonkillable(Variable *Dest, Operand *Src0,
280 CondARM32::Cond Pred = CondARM32::AL) { 286 CondARM32::Cond Pred = CondARM32::AL) {
281 Inst *NewInst = InstARM32Mov::create(Func, Dest, Src0, Pred); 287 Inst *NewInst = InstARM32Mov::create(Func, Dest, Src0, Pred);
282 NewInst->setDestNonKillable(); 288 NewInst->setDestNonKillable();
283 Context.insert(NewInst); 289 Context.insert(NewInst);
284 } 290 }
285 /// The Operand can only be a 16-bit immediate or a ConstantRelocatable (with 291 /// The Operand can only be a 16-bit immediate or a ConstantRelocatable (with
286 /// an upper16 relocation). 292 /// an upper16 relocation).
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 void _sbcs(Variable *Dest, Variable *Src0, Operand *Src1, 347 void _sbcs(Variable *Dest, Variable *Src0, Operand *Src1,
342 CondARM32::Cond Pred = CondARM32::AL) { 348 CondARM32::Cond Pred = CondARM32::AL) {
343 constexpr bool SetFlags = true; 349 constexpr bool SetFlags = true;
344 Context.insert( 350 Context.insert(
345 InstARM32Sbc::create(Func, Dest, Src0, Src1, Pred, SetFlags)); 351 InstARM32Sbc::create(Func, Dest, Src0, Src1, Pred, SetFlags));
346 } 352 }
347 void _sdiv(Variable *Dest, Variable *Src0, Variable *Src1, 353 void _sdiv(Variable *Dest, Variable *Src0, Variable *Src1,
348 CondARM32::Cond Pred = CondARM32::AL) { 354 CondARM32::Cond Pred = CondARM32::AL) {
349 Context.insert(InstARM32Sdiv::create(Func, Dest, Src0, Src1, Pred)); 355 Context.insert(InstARM32Sdiv::create(Func, Dest, Src0, Src1, Pred));
350 } 356 }
357 /// _str, for all your Variable to memory transfers. Addr has the same
358 /// restrictions that it does in _ldr.
351 void _str(Variable *Value, OperandARM32Mem *Addr, 359 void _str(Variable *Value, OperandARM32Mem *Addr,
352 CondARM32::Cond Pred = CondARM32::AL) { 360 CondARM32::Cond Pred = CondARM32::AL) {
353 Context.insert(InstARM32Str::create(Func, Value, Addr, Pred)); 361 Context.insert(InstARM32Str::create(Func, Value, Addr, Pred));
354 } 362 }
355 void _sub(Variable *Dest, Variable *Src0, Operand *Src1, 363 void _sub(Variable *Dest, Variable *Src0, Operand *Src1,
356 CondARM32::Cond Pred = CondARM32::AL) { 364 CondARM32::Cond Pred = CondARM32::AL) {
357 Context.insert(InstARM32Sub::create(Func, Dest, Src0, Src1, Pred)); 365 Context.insert(InstARM32Sub::create(Func, Dest, Src0, Src1, Pred));
358 } 366 }
359 void _subs(Variable *Dest, Variable *Src0, Operand *Src1, 367 void _subs(Variable *Dest, Variable *Src0, Operand *Src1,
360 CondARM32::Cond Pred = CondARM32::AL) { 368 CondARM32::Cond Pred = CondARM32::AL) {
(...skipping 19 matching lines...) Expand all
380 Context.insert( 388 Context.insert(
381 InstARM32Umull::create(Func, DestLo, DestHi, Src0, Src1, Pred)); 389 InstARM32Umull::create(Func, DestLo, DestHi, Src0, Src1, Pred));
382 // Model the modification to the second dest as a fake def. Note that the 390 // Model the modification to the second dest as a fake def. Note that the
383 // def is not predicated. 391 // def is not predicated.
384 Context.insert(InstFakeDef::create(Func, DestHi, DestLo)); 392 Context.insert(InstFakeDef::create(Func, DestHi, DestLo));
385 } 393 }
386 void _uxt(Variable *Dest, Variable *Src0, 394 void _uxt(Variable *Dest, Variable *Src0,
387 CondARM32::Cond Pred = CondARM32::AL) { 395 CondARM32::Cond Pred = CondARM32::AL) {
388 Context.insert(InstARM32Uxt::create(Func, Dest, Src0, Pred)); 396 Context.insert(InstARM32Uxt::create(Func, Dest, Src0, Pred));
389 } 397 }
398 void _vabs(Variable *Dest, Variable *Src,
399 CondARM32::Cond Pred = CondARM32::AL) {
400 Context.insert(InstARM32Vabs::create(Func, Dest, Src, Pred));
401 }
390 void _vadd(Variable *Dest, Variable *Src0, Variable *Src1) { 402 void _vadd(Variable *Dest, Variable *Src0, Variable *Src1) {
391 Context.insert(InstARM32Vadd::create(Func, Dest, Src0, Src1)); 403 Context.insert(InstARM32Vadd::create(Func, Dest, Src0, Src1));
392 } 404 }
393 void _vcvt(Variable *Dest, Variable *Src, InstARM32Vcvt::VcvtVariant Variant, 405 void _vcvt(Variable *Dest, Variable *Src, InstARM32Vcvt::VcvtVariant Variant,
394 CondARM32::Cond Pred = CondARM32::AL) { 406 CondARM32::Cond Pred = CondARM32::AL) {
395 Context.insert(InstARM32Vcvt::create(Func, Dest, Src, Variant, Pred)); 407 Context.insert(InstARM32Vcvt::create(Func, Dest, Src, Variant, Pred));
396 } 408 }
397 void _vdiv(Variable *Dest, Variable *Src0, Variable *Src1) { 409 void _vdiv(Variable *Dest, Variable *Src0, Variable *Src1) {
398 Context.insert(InstARM32Vdiv::create(Func, Dest, Src0, Src1)); 410 Context.insert(InstARM32Vdiv::create(Func, Dest, Src0, Src1));
399 } 411 }
400 void _vldr(Variable *Dest, OperandARM32Mem *Src,
401 CondARM32::Cond Pred = CondARM32::AL) {
402 Context.insert(InstARM32Vldr::create(Func, Dest, Src, Pred));
403 }
404 void _vcmp(Variable *Src0, Variable *Src1, 412 void _vcmp(Variable *Src0, Variable *Src1,
405 CondARM32::Cond Pred = CondARM32::AL) { 413 CondARM32::Cond Pred = CondARM32::AL) {
406 Context.insert(InstARM32Vcmp::create(Func, Src0, Src1, Pred)); 414 Context.insert(InstARM32Vcmp::create(Func, Src0, Src1, Pred));
407 } 415 }
408 void _vmrs(CondARM32::Cond Pred = CondARM32::AL) { 416 void _vmrs(CondARM32::Cond Pred = CondARM32::AL) {
409 Context.insert(InstARM32Vmrs::create(Func, Pred)); 417 Context.insert(InstARM32Vmrs::create(Func, Pred));
410 } 418 }
411 // There are a whole bunch of vmov variants, to transfer within S/D/Q
412 // registers, between core integer registers and S/D, and from small
413 // immediates into S/D. For integer -> S/D/Q there is a variant which takes
414 // two integer register to fill a D, or to fill two consecutive S registers.
415 // Vmov can also be used to insert-element. E.g.,
416 // "vmov.8 d0[1], r0"
417 // but insert-element is a "two-address" operation where only part of the
418 // register is modified. This cannot model that.
419 //
420 // This represents the simple single source, single dest variants only.
421 void _vmov(Variable *Dest, Operand *Src0,
422 CondARM32::Cond Pred = CondARM32::AL) {
423 Context.insert(InstARM32Vmov::create(Func, Dest, Src0, Pred));
424 }
425 // This represents the single source, multi dest variant.
426 void _vmov(InstARM32Vmov::RegisterPair Dests, Variable *Src0) {
427 constexpr CondARM32::Cond Pred = CondARM32::AL;
428 Context.insert(InstARM32Vmov::create(Func, Dests, Src0, Pred));
429 // The Vmov instruction created above does not define Dests._1. Therefore
430 // we add a Dest._1 = FakeDef pseudo instruction.
431 Context.insert(InstFakeDef::create(Func, Dests._1));
432 }
433 // This represents the multi source, single dest variant.
434 void _vmov(Variable *Dest, InstARM32Vmov::RegisterPair Srcs) {
435 constexpr CondARM32::Cond Pred = CondARM32::AL;
436 Context.insert(InstARM32Vmov::create(Func, Dest, Srcs, Pred));
437 }
438 void _vmul(Variable *Dest, Variable *Src0, Variable *Src1) { 419 void _vmul(Variable *Dest, Variable *Src0, Variable *Src1) {
439 Context.insert(InstARM32Vmul::create(Func, Dest, Src0, Src1)); 420 Context.insert(InstARM32Vmul::create(Func, Dest, Src0, Src1));
440 } 421 }
441 void _vsqrt(Variable *Dest, Variable *Src, 422 void _vsqrt(Variable *Dest, Variable *Src,
442 CondARM32::Cond Pred = CondARM32::AL) { 423 CondARM32::Cond Pred = CondARM32::AL) {
443 Context.insert(InstARM32Vsqrt::create(Func, Dest, Src, Pred)); 424 Context.insert(InstARM32Vsqrt::create(Func, Dest, Src, Pred));
444 } 425 }
445 void _vsub(Variable *Dest, Variable *Src0, Variable *Src1) { 426 void _vsub(Variable *Dest, Variable *Src0, Variable *Src1) {
446 Context.insert(InstARM32Vsub::create(Func, Dest, Src0, Src1)); 427 Context.insert(InstARM32Vsub::create(Func, Dest, Src0, Src1));
447 } 428 }
448 429
449 /// Run a pass through stack variables and ensure that the offsets are legal. 430 /// Run a pass through stack variables and ensure that the offsets are legal.
450 /// If the offset is not legal, use a new base register that accounts for the 431 /// If the offset is not legal, use a new base register that accounts for the
451 /// offset, such that the addressing mode offset bits are now legal. 432 /// offset, such that the addressing mode offset bits are now legal.
452 void legalizeStackSlots(); 433 void legalizeStackSlots();
453 /// Returns true if the given Offset can be represented in a stack ldr/str. 434 /// Returns true if the given Offset can be represented in a stack ldr/str.
454 bool isLegalVariableStackOffset(int32_t Offset) const; 435 bool isLegalVariableStackOffset(Type Ty, int32_t Offset) const;
455 /// Assuming Var needs its offset legalized, define a new base register 436 /// Assuming Var needs its offset legalized, define a new base register
456 /// centered on the given Var's offset and use it. 437 /// centered on the given Var's offset plus StackAdjust, and use it.
457 StackVariable *legalizeVariableSlot(Variable *Var, Variable *OrigBaseReg); 438 StackVariable *legalizeVariableSlot(Variable *Var, int32_t StackAdjust,
439 Variable *OrigBaseReg);
458 440
459 TargetARM32Features CPUFeatures; 441 TargetARM32Features CPUFeatures;
460 bool UsesFramePointer = false; 442 bool UsesFramePointer = false;
461 bool NeedsStackAlignment = false; 443 bool NeedsStackAlignment = false;
462 bool MaybeLeafFunc = true; 444 bool MaybeLeafFunc = true;
463 size_t SpillAreaSizeBytes = 0; 445 size_t SpillAreaSizeBytes = 0;
464 // TODO(jpp): std::array instead of array. 446 // TODO(jpp): std::array instead of array.
465 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM]; 447 llvm::SmallBitVector TypeToRegisterSet[IceType_NUM];
466 llvm::SmallBitVector RegisterAliases[RegARM32::Reg_NUM]; 448 llvm::SmallBitVector RegisterAliases[RegARM32::Reg_NUM];
467 llvm::SmallBitVector ScratchRegs; 449 llvm::SmallBitVector ScratchRegs;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 541
560 private: 542 private:
561 ~TargetHeaderARM32() = default; 543 ~TargetHeaderARM32() = default;
562 544
563 TargetARM32Features CPUFeatures; 545 TargetARM32Features CPUFeatures;
564 }; 546 };
565 547
566 } // end of namespace Ice 548 } // end of namespace Ice
567 549
568 #endif // SUBZERO_SRC_ICETARGETLOWERINGARM32_H 550 #endif // SUBZERO_SRC_ICETARGETLOWERINGARM32_H
OLDNEW
« no previous file with comments | « src/IceInstARM32.def ('k') | src/IceTargetLoweringARM32.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698