OSDN Git Service

Subzero. X8664. Fixes various small bugs.
authorJohn Porto <jpp@chromium.org>
Wed, 27 Jan 2016 14:31:53 +0000 (06:31 -0800)
committerJohn Porto <jpp@chromium.org>
Wed, 27 Jan 2016 14:31:53 +0000 (06:31 -0800)
These were all pointed out by the llvm test suite, the gcc torture
tests, and the scons tests.

BUG= https://bugs.chromium.org/p/nativeclient/issues/detail?id=4077
R=stichnot@chromium.org

Review URL: https://codereview.chromium.org/1631383002 .

src/IceAssemblerX86Base.h
src/IceAssemblerX86BaseImpl.h
src/IceInstX86BaseImpl.h
src/IceTargetLoweringX86BaseImpl.h

index e155a62..e76e0d1 100644 (file)
@@ -682,6 +682,7 @@ public:
   void jmp(GPRRegister reg);
   void jmp(Label *label, bool near = kFarJump);
   void jmp(const ConstantRelocatable *label); // not testable.
+  void jmp(const Immediate &abs_address);
 
   void mfence();
 
index 0035eee..212b234 100644 (file)
@@ -3177,6 +3177,17 @@ void AssemblerX86Base<TraitsType>::jmp(const ConstantRelocatable *label) {
   emitInt32(-4);
 }
 
+template <typename TraitsType>
+void AssemblerX86Base<TraitsType>::jmp(const Immediate &abs_address) {
+  AssemblerBuffer::EnsureCapacity ensured(&Buffer);
+  emitUint8(0xE9);
+  AssemblerFixup *Fixup =
+      this->createFixup(Traits::FK_PcRel, AssemblerFixup::NullSymbol);
+  Fixup->set_addend(abs_address.value());
+  emitFixup(Fixup);
+  emitInt32(abs_address.value() - 4);
+}
+
 template <typename TraitsType> void AssemblerX86Base<TraitsType>::mfence() {
   AssemblerBuffer::EnsureCapacity ensured(&Buffer);
   emitUint8(0x0F);
index 5bcd869..e9d3c86 100644 (file)
@@ -601,10 +601,7 @@ void InstImpl<TraitsType>::InstX86Jmp::emitIAS(const Cfg *Func) const {
     // NaCl trampoline calls refer to an address within the sandbox directly.
     // This is usually only needed for non-IRT builds and otherwise not very
     // portable or stable. Usually this is only done for "calls" and not jumps.
-    // TODO(jvoung): Support this when there is a lowering that actually
-    // triggers this case.
-    (void)Imm;
-    llvm::report_fatal_error("Unexpected jmp to absolute address");
+    Asm->jmp(AssemblerImmediate(Imm->getValue()));
   } else {
     llvm::report_fatal_error("Unexpected operand type");
   }
index 01e2be0..48c342f 100644 (file)
@@ -2488,7 +2488,8 @@ void TargetX86Base<TraitsType>::lowerCall(const InstCall *Instr) {
                              Variable::NoRegister)) {
       XmmArgs.push_back(Arg);
     } else if (isScalarFloatingType(Ty) && Traits::X86_PASS_SCALAR_FP_IN_XMM &&
-               (Traits::getRegisterForXmmArgNum(0) != Variable::NoRegister)) {
+               (Traits::getRegisterForXmmArgNum(XmmArgs.size()) !=
+                Variable::NoRegister)) {
       XmmArgs.push_back(Arg);
     } else if (isScalarIntegerType(Ty) &&
                (Traits::getRegisterForGprArgNum(Ty, GprArgs.size()) !=
@@ -4600,27 +4601,30 @@ void TargetX86Base<TraitsType>::lowerCountZeros(bool Cttz, Type Ty,
   //
   // Otherwise:
   //   bsr IF_NOT_ZERO, Val
-  //   mov T_DEST, 63
+  //   mov T_DEST, ((Ty == i32) ? 63 : 127)
   //   cmovne T_DEST, IF_NOT_ZERO
-  //   xor T_DEST, 31
+  //   xor T_DEST, ((Ty == i32) ? 31 : 63)
   //   mov DEST, T_DEST
   //
   // NOTE: T_DEST must be a register because cmov requires its dest to be a
   // register. Also, bsf and bsr require their dest to be a register.
   //
-  // The xor DEST, 31 converts a bit position to # of leading zeroes.
+  // The xor DEST, C(31|63) converts a bit position to # of leading zeroes.
   // E.g., for 000... 00001100, bsr will say that the most significant bit
   // set is at position 3, while the number of leading zeros is 28. Xor is
-  // like (31 - N) for N <= 31, and converts 63 to 32 (for the all-zeros case).
+  // like (M - N) for N <= M, and converts 63 to 32, and 127 to 64 (for the
+  // all-zeros case).
   //
-  // Similar for 64-bit, but start w/ speculating that the upper 32 bits
-  // are all zero, and compute the result for that case (checking the lower
-  // 32 bits). Then actually compute the result for the upper bits and
+  // X8632 only: Similar for 64-bit, but start w/ speculating that the upper 32
+  // bits are all zero, and compute the result for that case (checking the
+  // lower 32 bits). Then actually compute the result for the upper bits and
   // cmov in the result from the lower computation if the earlier speculation
   // was correct.
   //
   // Cttz, is similar, but uses bsf instead, and doesn't require the xor
   // bit position conversion, and the speculation is reversed.
+
+  // TODO(jpp): refactor this method.
   assert(Ty == IceType_i32 || Ty == IceType_i64);
   const Type DestTy = Traits::Is64Bit ? Dest->getType() : IceType_i32;
   Variable *T = makeReg(DestTy);
@@ -4633,15 +4637,32 @@ void TargetX86Base<TraitsType>::lowerCountZeros(bool Cttz, Type Ty,
   Variable *T_Dest = makeReg(DestTy);
   Constant *_31 = Ctx->getConstantInt32(31);
   Constant *_32 = Ctx->getConstantInt(DestTy, 32);
+  Constant *_63 = Ctx->getConstantInt(DestTy, 63);
+  Constant *_64 = Ctx->getConstantInt(DestTy, 64);
   if (Cttz) {
-    _mov(T_Dest, _32);
+    if (DestTy == IceType_i64) {
+      _mov(T_Dest, _64);
+    } else {
+      _mov(T_Dest, _32);
+    }
   } else {
-    Constant *_63 = Ctx->getConstantInt(DestTy, 63);
-    _mov(T_Dest, _63);
+    Constant *_127 = Ctx->getConstantInt(DestTy, 127);
+    if (DestTy == IceType_i64) {
+      _mov(T_Dest, _127);
+    } else {
+      _mov(T_Dest, _63);
+    }
   }
   _cmov(T_Dest, T, Traits::Cond::Br_ne);
   if (!Cttz) {
-    _xor(T_Dest, _31);
+    if (DestTy == IceType_i64) {
+      // Even though there's a _63 available at this point, that constant might
+      // not be an i32, which will cause the xor emission to fail.
+      Constant *_63 = Ctx->getConstantInt32(63);
+      _xor(T_Dest, _63);
+    } else {
+      _xor(T_Dest, _31);
+    }
   }
   if (Traits::Is64Bit || Ty == IceType_i32) {
     _mov(Dest, T_Dest);