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

Side by Side Diff: src/IceTargetLoweringARM32.cpp

Issue 1127003003: Lower a few basic ARM binops for i{8,16,32,64}. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: added condition and target to test Created 5 years, 7 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/IceTargetLoweringARM32.h ('k') | tests_lit/llvm2ice_tests/arith.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/IceTargetLoweringARM32.cpp - ARM32 lowering ------------===// 1 //===- subzero/src/IceTargetLoweringARM32.cpp - ARM32 lowering ------------===//
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 // This file implements the TargetLoweringARM32 class, which consists almost 10 // This file implements the TargetLoweringARM32 class, which consists almost
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 533
534 void TargetARM32::lowerArithmetic(const InstArithmetic *Inst) { 534 void TargetARM32::lowerArithmetic(const InstArithmetic *Inst) {
535 Variable *Dest = Inst->getDest(); 535 Variable *Dest = Inst->getDest();
536 // TODO(jvoung): Should be able to flip Src0 and Src1 if it is easier 536 // TODO(jvoung): Should be able to flip Src0 and Src1 if it is easier
537 // to legalize Src0 to flex or Src1 to flex and there is a reversible 537 // to legalize Src0 to flex or Src1 to flex and there is a reversible
538 // instruction. E.g., reverse subtract with immediate, register vs 538 // instruction. E.g., reverse subtract with immediate, register vs
539 // register, immediate. 539 // register, immediate.
540 // Or it may be the case that the operands aren't swapped, but the 540 // Or it may be the case that the operands aren't swapped, but the
541 // bits can be flipped and a different operation applied. 541 // bits can be flipped and a different operation applied.
542 // E.g., use BIC (bit clear) instead of AND for some masks. 542 // E.g., use BIC (bit clear) instead of AND for some masks.
543 Variable *Src0 = legalizeToVar(Inst->getSrc(0)); 543 Operand *Src0 = Inst->getSrc(0);
544 Operand *Src1 = legalize(Inst->getSrc(1), Legal_Reg | Legal_Flex); 544 Operand *Src1 = Inst->getSrc(1);
545 (void)Src0;
546 (void)Src1;
547 if (Dest->getType() == IceType_i64) { 545 if (Dest->getType() == IceType_i64) {
548 UnimplementedError(Func->getContext()->getFlags()); 546 Variable *DestLo = llvm::cast<Variable>(loOperand(Dest));
547 Variable *DestHi = llvm::cast<Variable>(hiOperand(Dest));
548 Variable *Src0RLo = legalizeToVar(loOperand(Src0));
549 Variable *Src0RHi = legalizeToVar(hiOperand(Src0));
550 Operand *Src1Lo = legalize(loOperand(Src1), Legal_Reg | Legal_Flex);
551 Operand *Src1Hi = legalize(hiOperand(Src1), Legal_Reg | Legal_Flex);
552 Variable *T_Lo = makeReg(DestLo->getType());
553 Variable *T_Hi = makeReg(DestHi->getType());
554 switch (Inst->getOp()) {
555 case InstArithmetic::_num:
556 llvm_unreachable("Unknown arithmetic operator");
557 break;
558 case InstArithmetic::Add:
559 _adds(T_Lo, Src0RLo, Src1Lo);
560 _mov(DestLo, T_Lo);
561 _adc(T_Hi, Src0RHi, Src1Hi);
562 _mov(DestHi, T_Hi);
563 break;
564 case InstArithmetic::And:
565 _and(T_Lo, Src0RLo, Src1Lo);
566 _mov(DestLo, T_Lo);
567 _and(T_Hi, Src0RHi, Src1Hi);
568 _mov(DestHi, T_Hi);
569 break;
570 case InstArithmetic::Or:
571 _orr(T_Lo, Src0RLo, Src1Lo);
572 _mov(DestLo, T_Lo);
573 _orr(T_Hi, Src0RHi, Src1Hi);
574 _mov(DestHi, T_Hi);
575 break;
576 case InstArithmetic::Xor:
577 _eor(T_Lo, Src0RLo, Src1Lo);
578 _mov(DestLo, T_Lo);
579 _eor(T_Hi, Src0RHi, Src1Hi);
580 _mov(DestHi, T_Hi);
581 break;
582 case InstArithmetic::Sub:
583 _subs(T_Lo, Src0RLo, Src1Lo);
584 _mov(DestLo, T_Lo);
585 _sbc(T_Hi, Src0RHi, Src1Hi);
586 _mov(DestHi, T_Hi);
587 break;
588 case InstArithmetic::Mul: {
589 // GCC 4.8 does:
590 // a=b*c ==>
591 // t_acc =(mul) (b.lo * c.hi)
592 // t_acc =(mla) (c.lo * b.hi) + t_acc
593 // t.hi,t.lo =(umull) b.lo * c.lo
594 // t.hi += t_acc
595 // a.lo = t.lo
596 // a.hi = t.hi
597 //
598 // LLVM does:
599 // t.hi,t.lo =(umull) b.lo * c.lo
600 // t.hi =(mla) (b.lo * c.hi) + t.hi
601 // t.hi =(mla) (b.hi * c.lo) + t.hi
602 // a.lo = t.lo
603 // a.hi = t.hi
604 //
605 // LLVM's lowering has fewer instructions, but more register pressure:
606 // t.lo is live from beginning to end, while GCC delays the two-dest
607 // instruction till the end, and kills c.hi immediately.
608 Variable *T_Acc = makeReg(IceType_i32);
609 Variable *T_Acc1 = makeReg(IceType_i32);
610 Variable *T_Hi1 = makeReg(IceType_i32);
611 Variable *Src1RLo = legalizeToVar(Src1Lo);
612 Variable *Src1RHi = legalizeToVar(Src1Hi);
613 _mul(T_Acc, Src0RLo, Src1RHi);
614 _mla(T_Acc1, Src1RLo, Src0RHi, T_Acc);
615 _umull(T_Lo, T_Hi1, Src0RLo, Src1RLo);
616 _add(T_Hi, T_Hi1, T_Acc1);
617 _mov(DestLo, T_Lo);
618 _mov(DestHi, T_Hi);
619 } break;
620 case InstArithmetic::Shl:
621 case InstArithmetic::Lshr:
622 case InstArithmetic::Ashr:
623 case InstArithmetic::Udiv:
624 case InstArithmetic::Sdiv:
625 case InstArithmetic::Urem:
626 case InstArithmetic::Srem:
627 UnimplementedError(Func->getContext()->getFlags());
628 break;
629 case InstArithmetic::Fadd:
630 case InstArithmetic::Fsub:
631 case InstArithmetic::Fmul:
632 case InstArithmetic::Fdiv:
633 case InstArithmetic::Frem:
634 llvm_unreachable("FP instruction with i64 type");
635 break;
636 }
549 } else if (isVectorType(Dest->getType())) { 637 } else if (isVectorType(Dest->getType())) {
550 UnimplementedError(Func->getContext()->getFlags()); 638 UnimplementedError(Func->getContext()->getFlags());
551 } else { // Dest->getType() is non-i64 scalar 639 } else { // Dest->getType() is non-i64 scalar
640 Variable *Src0R = legalizeToVar(Inst->getSrc(0));
641 Src1 = legalize(Inst->getSrc(1), Legal_Reg | Legal_Flex);
642 Variable *T = makeReg(Dest->getType());
552 switch (Inst->getOp()) { 643 switch (Inst->getOp()) {
553 case InstArithmetic::_num: 644 case InstArithmetic::_num:
554 llvm_unreachable("Unknown arithmetic operator"); 645 llvm_unreachable("Unknown arithmetic operator");
555 break; 646 break;
556 case InstArithmetic::Add: { 647 case InstArithmetic::Add: {
557 UnimplementedError(Func->getContext()->getFlags()); 648 _add(T, Src0R, Src1);
558 // Variable *T = makeReg(Dest->getType()); 649 _mov(Dest, T);
559 // _add(T, Src0, Src1);
560 // _mov(Dest, T);
561 } break; 650 } break;
562 case InstArithmetic::And: 651 case InstArithmetic::And: {
563 UnimplementedError(Func->getContext()->getFlags()); 652 _and(T, Src0R, Src1);
564 break; 653 _mov(Dest, T);
565 case InstArithmetic::Or: 654 } break;
566 UnimplementedError(Func->getContext()->getFlags()); 655 case InstArithmetic::Or: {
567 break; 656 _orr(T, Src0R, Src1);
568 case InstArithmetic::Xor: 657 _mov(Dest, T);
569 UnimplementedError(Func->getContext()->getFlags()); 658 } break;
570 break; 659 case InstArithmetic::Xor: {
571 case InstArithmetic::Sub: 660 _eor(T, Src0R, Src1);
572 UnimplementedError(Func->getContext()->getFlags()); 661 _mov(Dest, T);
573 break; 662 } break;
574 case InstArithmetic::Mul: 663 case InstArithmetic::Sub: {
575 UnimplementedError(Func->getContext()->getFlags()); 664 _sub(T, Src0R, Src1);
576 break; 665 _mov(Dest, T);
666 } break;
667 case InstArithmetic::Mul: {
668 Variable *Src1R = legalizeToVar(Src1);
669 _mul(T, Src0R, Src1R);
670 _mov(Dest, T);
671 } break;
577 case InstArithmetic::Shl: 672 case InstArithmetic::Shl:
578 UnimplementedError(Func->getContext()->getFlags()); 673 UnimplementedError(Func->getContext()->getFlags());
579 break; 674 break;
580 case InstArithmetic::Lshr: 675 case InstArithmetic::Lshr:
581 UnimplementedError(Func->getContext()->getFlags()); 676 UnimplementedError(Func->getContext()->getFlags());
582 break; 677 break;
583 case InstArithmetic::Ashr: 678 case InstArithmetic::Ashr:
584 UnimplementedError(Func->getContext()->getFlags()); 679 UnimplementedError(Func->getContext()->getFlags());
585 break; 680 break;
586 case InstArithmetic::Udiv: 681 case InstArithmetic::Udiv:
(...skipping 610 matching lines...) Expand 10 before | Expand all | Expand 10 after
1197 } 1292 }
1198 } 1293 }
1199 1294
1200 void TargetDataARM32::lowerConstants() const { 1295 void TargetDataARM32::lowerConstants() const {
1201 if (Ctx->getFlags().getDisableTranslation()) 1296 if (Ctx->getFlags().getDisableTranslation())
1202 return; 1297 return;
1203 UnimplementedError(Ctx->getFlags()); 1298 UnimplementedError(Ctx->getFlags());
1204 } 1299 }
1205 1300
1206 } // end of namespace Ice 1301 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceTargetLoweringARM32.h ('k') | tests_lit/llvm2ice_tests/arith.ll » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698