Hi David,<br><br>I'm catching up on email at the moment so I don't know if you've done this, but patches should go to llvm-commits for review if you wouldn't mind.<div><br></div><div>Thanks!</div><div><br></div>
<div>-eric</div><br><div>On Thu Dec 12 2013 at 8:39:19 AM, David Woodhouse <<a href="mailto:dwmw2@infradead.org">dwmw2@infradead.org</a>> wrote:</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
This attempts to address <a href="http://llvm.org/bugs/show_bug.cgi?id=18220" target="_blank">http://llvm.org/bugs/show_bug.<u></u>cgi?id=18220</a><br>
It also fixes a test which was requiring the *wrong* output.<br>
<br>
I'm relatively happy with this part, and it even solves most of the hard<br>
part of feature request for .code16 in bug 8684 — which was actually why<br>
I started prodding at this. But I could do with some help with the<br>
16-bit signed relocation handling, which I've split into a subsequent<br>
patch.<br>
<br>
diff --git a/lib/Target/X86/MCTargetDesc/<u></u>X86MCCodeEmitter.cpp b/lib/Target/X86/MCTargetDesc/<u></u>X86MCCodeEmitter.cpp<br>
index 7952607..12a30cf 100644<br>
--- a/lib/Target/X86/MCTargetDesc/<u></u>X86MCCodeEmitter.cpp<br>
+++ b/lib/Target/X86/MCTargetDesc/<u></u>X86MCCodeEmitter.cpp<br>
@@ -402,6 +402,56 @@ void X86MCCodeEmitter::<u></u>EmitMemModRMByte(const MCInst &MI, unsigned Op,<br>
<br>
   unsigned BaseRegNo = BaseReg ? GetX86RegNum(Base) : -1U;<br>
<br>
+  // 16-bit addressing forms of the ModR/M byte have a different encoding for<br>
+  // the R/M field and are far more limited in which registers can be used.<br>
+  if (Is16BitMemOperand(MI, Op)) {<br>
+    if (BaseReg) {<br>
+      // See Table 2-1 "16-Bit Addressing Forms with the ModR/M byte"<br>
+      static const int R16Table[] = { 0, 0, 0, 7, 0, 6, 4, 5 };<br>
+      unsigned RMfield = R16Table[BaseRegNo];<br>
+<br>
+      assert(RMfield && "invalid 16-bit base register");<br>
+<br>
+      if (IndexReg.getReg()) {<br>
+        unsigned IndexReg16 = R16Table[GetX86RegNum(<u></u>IndexReg)];<br>
+<br>
+        // Must have one of SI,DI (4,5), and one of BP/BX (6,7)<br>
+        assert(((IndexReg16 ^ RMfield) & 2) &&<br>
+               "invalid 16-bit base/index register combination");<br>
+        assert(Scale.getImm() == 1 &&<br>
+               "invalid scale for 16-bit memory reference");<br>
+<br>
+        if (IndexReg16 & 2)<br>
+          RMfield = (RMfield & 1) | ((7 - IndexReg16) << 1);<br>
+        else<br>
+          RMfield = (IndexReg16 & 1) | ((7 - RMfield) << 1);<br>
+      }<br>
+<br>
+      if (Disp.isImm() && isDisp8(Disp.getImm())) {<br>
+        // Use [REG]+disp8 form if we can, and for [BP] which cannot be encoded.<br>
+        if (BaseRegNo == N86::EBP || Disp.getImm() != 0) {<br>
+          EmitByte(ModRMByte(1, RegOpcodeField, RMfield), CurByte, OS);<br>
+          EmitImmediate(Disp, MI.getLoc(), 1, FK_Data_1, CurByte, OS, Fixups);<br>
+          return;<br>
+        } else {<br>
+          // No displacement<br>
+          EmitByte(ModRMByte(0, RegOpcodeField, RMfield), CurByte, OS);<br>
+          return;<br>
+        }<br>
+      }<br>
+      EmitByte(ModRMByte(2, RegOpcodeField, RMfield), CurByte, OS);<br>
+    } else {<br>
+      // !BaseReg<br>
+      EmitByte(ModRMByte(0, RegOpcodeField, 6), CurByte, OS);<br>
+    }<br>
+<br>
+    // FIXME: Yes we can!<br>
+    assert(Disp.isImm() && "cannot emit 16-bit relocation");<br>
+    // Emit 16-bit displacement for plain disp16 or [REG]+disp16 cases.<br>
+    EmitImmediate(Disp, MI.getLoc(), 2, FK_Data_2, CurByte, OS, Fixups);<br>
+    return;<br>
+  }<br>
+<br>
   // Determine whether a SIB byte is needed.<br>
   // If no BaseReg, issue a RIP relative instruction only if the MCE can<br>
   // resolve addresses on-the-fly, otherwise use SIB (Intel Manual 2A, table<br>
diff --git a/test/MC/X86/address-size.s b/test/MC/X86/address-size.s<br>
index b105b40..7b0bf6b 100644<br>
--- a/test/MC/X86/address-size.s<br>
+++ b/test/MC/X86/address-size.s<br>
@@ -8,6 +8,6 @@<br>
<br>
        .code32<br>
        movb    $0x0, (%si)<br>
-// CHECK: encoding: [0x67,0xc6,0x06,0x00]<br>
+// CHECK: encoding: [0x67,0xc6,0x04,0x00]<br>
        movb    $0x0, (%esi)<br>
 // CHECK: encoding: [0xc6,0x06,0x00]<br>
--<br>
1.8.3.1<br>
<br>
<br>
--<br>
                   Sent with MeeGo's ActiveSync support.<br>
<br>
David Woodhouse                            Open Source Technology Centre<br>
<a href="mailto:David.Woodhouse@intel.com" target="_blank">David.Woodhouse@intel.com</a>                              Intel Corporation<br>
<br>
<br>
<br>
______________________________<u></u>_________________<br>
LLVM Developers mailing list<br>
<a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/<u></u>mailman/listinfo/llvmdev</a><br>
</blockquote>