Home | History | Annotate | Download | only in x86
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "assembler_x86.h"
     18 
     19 #include "base/casts.h"
     20 #include "entrypoints/quick/quick_entrypoints.h"
     21 #include "memory_region.h"
     22 #include "thread.h"
     23 
     24 namespace art {
     25 namespace x86 {
     26 
     27 class DirectCallRelocation : public AssemblerFixup {
     28  public:
     29   void Process(const MemoryRegion& region, int position) {
     30     // Direct calls are relative to the following instruction on x86.
     31     int32_t pointer = region.Load<int32_t>(position);
     32     int32_t start = reinterpret_cast<int32_t>(region.start());
     33     int32_t delta = start + position + sizeof(int32_t);
     34     region.Store<int32_t>(position, pointer - delta);
     35   }
     36 };
     37 
     38 std::ostream& operator<<(std::ostream& os, const XmmRegister& reg) {
     39   return os << "XMM" << static_cast<int>(reg);
     40 }
     41 
     42 std::ostream& operator<<(std::ostream& os, const X87Register& reg) {
     43   return os << "ST" << static_cast<int>(reg);
     44 }
     45 
     46 void X86Assembler::call(Register reg) {
     47   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
     48   EmitUint8(0xFF);
     49   EmitRegisterOperand(2, reg);
     50 }
     51 
     52 
     53 void X86Assembler::call(const Address& address) {
     54   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
     55   EmitUint8(0xFF);
     56   EmitOperand(2, address);
     57 }
     58 
     59 
     60 void X86Assembler::call(Label* label) {
     61   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
     62   EmitUint8(0xE8);
     63   static const int kSize = 5;
     64   EmitLabel(label, kSize);
     65 }
     66 
     67 
     68 void X86Assembler::pushl(Register reg) {
     69   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
     70   EmitUint8(0x50 + reg);
     71 }
     72 
     73 
     74 void X86Assembler::pushl(const Address& address) {
     75   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
     76   EmitUint8(0xFF);
     77   EmitOperand(6, address);
     78 }
     79 
     80 
     81 void X86Assembler::pushl(const Immediate& imm) {
     82   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
     83   if (imm.is_int8()) {
     84     EmitUint8(0x6A);
     85     EmitUint8(imm.value() & 0xFF);
     86   } else {
     87     EmitUint8(0x68);
     88     EmitImmediate(imm);
     89   }
     90 }
     91 
     92 
     93 void X86Assembler::popl(Register reg) {
     94   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
     95   EmitUint8(0x58 + reg);
     96 }
     97 
     98 
     99 void X86Assembler::popl(const Address& address) {
    100   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    101   EmitUint8(0x8F);
    102   EmitOperand(0, address);
    103 }
    104 
    105 
    106 void X86Assembler::movl(Register dst, const Immediate& imm) {
    107   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    108   EmitUint8(0xB8 + dst);
    109   EmitImmediate(imm);
    110 }
    111 
    112 
    113 void X86Assembler::movl(Register dst, Register src) {
    114   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    115   EmitUint8(0x89);
    116   EmitRegisterOperand(src, dst);
    117 }
    118 
    119 
    120 void X86Assembler::movl(Register dst, const Address& src) {
    121   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    122   EmitUint8(0x8B);
    123   EmitOperand(dst, src);
    124 }
    125 
    126 
    127 void X86Assembler::movl(const Address& dst, Register src) {
    128   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    129   EmitUint8(0x89);
    130   EmitOperand(src, dst);
    131 }
    132 
    133 
    134 void X86Assembler::movl(const Address& dst, const Immediate& imm) {
    135   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    136   EmitUint8(0xC7);
    137   EmitOperand(0, dst);
    138   EmitImmediate(imm);
    139 }
    140 
    141 void X86Assembler::movl(const Address& dst, Label* lbl) {
    142   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    143   EmitUint8(0xC7);
    144   EmitOperand(0, dst);
    145   EmitLabel(lbl, dst.length_ + 5);
    146 }
    147 
    148 void X86Assembler::movzxb(Register dst, ByteRegister src) {
    149   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    150   EmitUint8(0x0F);
    151   EmitUint8(0xB6);
    152   EmitRegisterOperand(dst, src);
    153 }
    154 
    155 
    156 void X86Assembler::movzxb(Register dst, const Address& src) {
    157   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    158   EmitUint8(0x0F);
    159   EmitUint8(0xB6);
    160   EmitOperand(dst, src);
    161 }
    162 
    163 
    164 void X86Assembler::movsxb(Register dst, ByteRegister src) {
    165   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    166   EmitUint8(0x0F);
    167   EmitUint8(0xBE);
    168   EmitRegisterOperand(dst, src);
    169 }
    170 
    171 
    172 void X86Assembler::movsxb(Register dst, const Address& src) {
    173   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    174   EmitUint8(0x0F);
    175   EmitUint8(0xBE);
    176   EmitOperand(dst, src);
    177 }
    178 
    179 
    180 void X86Assembler::movb(Register /*dst*/, const Address& /*src*/) {
    181   LOG(FATAL) << "Use movzxb or movsxb instead.";
    182 }
    183 
    184 
    185 void X86Assembler::movb(const Address& dst, ByteRegister src) {
    186   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    187   EmitUint8(0x88);
    188   EmitOperand(src, dst);
    189 }
    190 
    191 
    192 void X86Assembler::movb(const Address& dst, const Immediate& imm) {
    193   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    194   EmitUint8(0xC6);
    195   EmitOperand(EAX, dst);
    196   CHECK(imm.is_int8());
    197   EmitUint8(imm.value() & 0xFF);
    198 }
    199 
    200 
    201 void X86Assembler::movzxw(Register dst, Register src) {
    202   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    203   EmitUint8(0x0F);
    204   EmitUint8(0xB7);
    205   EmitRegisterOperand(dst, src);
    206 }
    207 
    208 
    209 void X86Assembler::movzxw(Register dst, const Address& src) {
    210   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    211   EmitUint8(0x0F);
    212   EmitUint8(0xB7);
    213   EmitOperand(dst, src);
    214 }
    215 
    216 
    217 void X86Assembler::movsxw(Register dst, Register src) {
    218   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    219   EmitUint8(0x0F);
    220   EmitUint8(0xBF);
    221   EmitRegisterOperand(dst, src);
    222 }
    223 
    224 
    225 void X86Assembler::movsxw(Register dst, const Address& src) {
    226   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    227   EmitUint8(0x0F);
    228   EmitUint8(0xBF);
    229   EmitOperand(dst, src);
    230 }
    231 
    232 
    233 void X86Assembler::movw(Register /*dst*/, const Address& /*src*/) {
    234   LOG(FATAL) << "Use movzxw or movsxw instead.";
    235 }
    236 
    237 
    238 void X86Assembler::movw(const Address& dst, Register src) {
    239   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    240   EmitOperandSizeOverride();
    241   EmitUint8(0x89);
    242   EmitOperand(src, dst);
    243 }
    244 
    245 
    246 void X86Assembler::leal(Register dst, const Address& src) {
    247   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    248   EmitUint8(0x8D);
    249   EmitOperand(dst, src);
    250 }
    251 
    252 
    253 void X86Assembler::cmovl(Condition condition, Register dst, Register src) {
    254   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    255   EmitUint8(0x0F);
    256   EmitUint8(0x40 + condition);
    257   EmitRegisterOperand(dst, src);
    258 }
    259 
    260 
    261 void X86Assembler::setb(Condition condition, Register dst) {
    262   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    263   EmitUint8(0x0F);
    264   EmitUint8(0x90 + condition);
    265   EmitOperand(0, Operand(dst));
    266 }
    267 
    268 
    269 void X86Assembler::movss(XmmRegister dst, const Address& src) {
    270   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    271   EmitUint8(0xF3);
    272   EmitUint8(0x0F);
    273   EmitUint8(0x10);
    274   EmitOperand(dst, src);
    275 }
    276 
    277 
    278 void X86Assembler::movss(const Address& dst, XmmRegister src) {
    279   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    280   EmitUint8(0xF3);
    281   EmitUint8(0x0F);
    282   EmitUint8(0x11);
    283   EmitOperand(src, dst);
    284 }
    285 
    286 
    287 void X86Assembler::movss(XmmRegister dst, XmmRegister src) {
    288   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    289   EmitUint8(0xF3);
    290   EmitUint8(0x0F);
    291   EmitUint8(0x11);
    292   EmitXmmRegisterOperand(src, dst);
    293 }
    294 
    295 
    296 void X86Assembler::movd(XmmRegister dst, Register src) {
    297   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    298   EmitUint8(0x66);
    299   EmitUint8(0x0F);
    300   EmitUint8(0x6E);
    301   EmitOperand(dst, Operand(src));
    302 }
    303 
    304 
    305 void X86Assembler::movd(Register dst, XmmRegister src) {
    306   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    307   EmitUint8(0x66);
    308   EmitUint8(0x0F);
    309   EmitUint8(0x7E);
    310   EmitOperand(src, Operand(dst));
    311 }
    312 
    313 
    314 void X86Assembler::addss(XmmRegister dst, XmmRegister src) {
    315   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    316   EmitUint8(0xF3);
    317   EmitUint8(0x0F);
    318   EmitUint8(0x58);
    319   EmitXmmRegisterOperand(dst, src);
    320 }
    321 
    322 
    323 void X86Assembler::addss(XmmRegister dst, const Address& src) {
    324   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    325   EmitUint8(0xF3);
    326   EmitUint8(0x0F);
    327   EmitUint8(0x58);
    328   EmitOperand(dst, src);
    329 }
    330 
    331 
    332 void X86Assembler::subss(XmmRegister dst, XmmRegister src) {
    333   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    334   EmitUint8(0xF3);
    335   EmitUint8(0x0F);
    336   EmitUint8(0x5C);
    337   EmitXmmRegisterOperand(dst, src);
    338 }
    339 
    340 
    341 void X86Assembler::subss(XmmRegister dst, const Address& src) {
    342   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    343   EmitUint8(0xF3);
    344   EmitUint8(0x0F);
    345   EmitUint8(0x5C);
    346   EmitOperand(dst, src);
    347 }
    348 
    349 
    350 void X86Assembler::mulss(XmmRegister dst, XmmRegister src) {
    351   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    352   EmitUint8(0xF3);
    353   EmitUint8(0x0F);
    354   EmitUint8(0x59);
    355   EmitXmmRegisterOperand(dst, src);
    356 }
    357 
    358 
    359 void X86Assembler::mulss(XmmRegister dst, const Address& src) {
    360   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    361   EmitUint8(0xF3);
    362   EmitUint8(0x0F);
    363   EmitUint8(0x59);
    364   EmitOperand(dst, src);
    365 }
    366 
    367 
    368 void X86Assembler::divss(XmmRegister dst, XmmRegister src) {
    369   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    370   EmitUint8(0xF3);
    371   EmitUint8(0x0F);
    372   EmitUint8(0x5E);
    373   EmitXmmRegisterOperand(dst, src);
    374 }
    375 
    376 
    377 void X86Assembler::divss(XmmRegister dst, const Address& src) {
    378   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    379   EmitUint8(0xF3);
    380   EmitUint8(0x0F);
    381   EmitUint8(0x5E);
    382   EmitOperand(dst, src);
    383 }
    384 
    385 
    386 void X86Assembler::flds(const Address& src) {
    387   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    388   EmitUint8(0xD9);
    389   EmitOperand(0, src);
    390 }
    391 
    392 
    393 void X86Assembler::fstps(const Address& dst) {
    394   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    395   EmitUint8(0xD9);
    396   EmitOperand(3, dst);
    397 }
    398 
    399 
    400 void X86Assembler::movsd(XmmRegister dst, const Address& src) {
    401   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    402   EmitUint8(0xF2);
    403   EmitUint8(0x0F);
    404   EmitUint8(0x10);
    405   EmitOperand(dst, src);
    406 }
    407 
    408 
    409 void X86Assembler::movsd(const Address& dst, XmmRegister src) {
    410   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    411   EmitUint8(0xF2);
    412   EmitUint8(0x0F);
    413   EmitUint8(0x11);
    414   EmitOperand(src, dst);
    415 }
    416 
    417 
    418 void X86Assembler::movsd(XmmRegister dst, XmmRegister src) {
    419   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    420   EmitUint8(0xF2);
    421   EmitUint8(0x0F);
    422   EmitUint8(0x11);
    423   EmitXmmRegisterOperand(src, dst);
    424 }
    425 
    426 
    427 void X86Assembler::addsd(XmmRegister dst, XmmRegister src) {
    428   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    429   EmitUint8(0xF2);
    430   EmitUint8(0x0F);
    431   EmitUint8(0x58);
    432   EmitXmmRegisterOperand(dst, src);
    433 }
    434 
    435 
    436 void X86Assembler::addsd(XmmRegister dst, const Address& src) {
    437   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    438   EmitUint8(0xF2);
    439   EmitUint8(0x0F);
    440   EmitUint8(0x58);
    441   EmitOperand(dst, src);
    442 }
    443 
    444 
    445 void X86Assembler::subsd(XmmRegister dst, XmmRegister src) {
    446   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    447   EmitUint8(0xF2);
    448   EmitUint8(0x0F);
    449   EmitUint8(0x5C);
    450   EmitXmmRegisterOperand(dst, src);
    451 }
    452 
    453 
    454 void X86Assembler::subsd(XmmRegister dst, const Address& src) {
    455   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    456   EmitUint8(0xF2);
    457   EmitUint8(0x0F);
    458   EmitUint8(0x5C);
    459   EmitOperand(dst, src);
    460 }
    461 
    462 
    463 void X86Assembler::mulsd(XmmRegister dst, XmmRegister src) {
    464   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    465   EmitUint8(0xF2);
    466   EmitUint8(0x0F);
    467   EmitUint8(0x59);
    468   EmitXmmRegisterOperand(dst, src);
    469 }
    470 
    471 
    472 void X86Assembler::mulsd(XmmRegister dst, const Address& src) {
    473   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    474   EmitUint8(0xF2);
    475   EmitUint8(0x0F);
    476   EmitUint8(0x59);
    477   EmitOperand(dst, src);
    478 }
    479 
    480 
    481 void X86Assembler::divsd(XmmRegister dst, XmmRegister src) {
    482   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    483   EmitUint8(0xF2);
    484   EmitUint8(0x0F);
    485   EmitUint8(0x5E);
    486   EmitXmmRegisterOperand(dst, src);
    487 }
    488 
    489 
    490 void X86Assembler::divsd(XmmRegister dst, const Address& src) {
    491   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    492   EmitUint8(0xF2);
    493   EmitUint8(0x0F);
    494   EmitUint8(0x5E);
    495   EmitOperand(dst, src);
    496 }
    497 
    498 
    499 void X86Assembler::cvtsi2ss(XmmRegister dst, Register src) {
    500   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    501   EmitUint8(0xF3);
    502   EmitUint8(0x0F);
    503   EmitUint8(0x2A);
    504   EmitOperand(dst, Operand(src));
    505 }
    506 
    507 
    508 void X86Assembler::cvtsi2sd(XmmRegister dst, Register src) {
    509   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    510   EmitUint8(0xF2);
    511   EmitUint8(0x0F);
    512   EmitUint8(0x2A);
    513   EmitOperand(dst, Operand(src));
    514 }
    515 
    516 
    517 void X86Assembler::cvtss2si(Register dst, XmmRegister src) {
    518   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    519   EmitUint8(0xF3);
    520   EmitUint8(0x0F);
    521   EmitUint8(0x2D);
    522   EmitXmmRegisterOperand(dst, src);
    523 }
    524 
    525 
    526 void X86Assembler::cvtss2sd(XmmRegister dst, XmmRegister src) {
    527   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    528   EmitUint8(0xF3);
    529   EmitUint8(0x0F);
    530   EmitUint8(0x5A);
    531   EmitXmmRegisterOperand(dst, src);
    532 }
    533 
    534 
    535 void X86Assembler::cvtsd2si(Register dst, XmmRegister src) {
    536   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    537   EmitUint8(0xF2);
    538   EmitUint8(0x0F);
    539   EmitUint8(0x2D);
    540   EmitXmmRegisterOperand(dst, src);
    541 }
    542 
    543 
    544 void X86Assembler::cvttss2si(Register dst, XmmRegister src) {
    545   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    546   EmitUint8(0xF3);
    547   EmitUint8(0x0F);
    548   EmitUint8(0x2C);
    549   EmitXmmRegisterOperand(dst, src);
    550 }
    551 
    552 
    553 void X86Assembler::cvttsd2si(Register dst, XmmRegister src) {
    554   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    555   EmitUint8(0xF2);
    556   EmitUint8(0x0F);
    557   EmitUint8(0x2C);
    558   EmitXmmRegisterOperand(dst, src);
    559 }
    560 
    561 
    562 void X86Assembler::cvtsd2ss(XmmRegister dst, XmmRegister src) {
    563   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    564   EmitUint8(0xF2);
    565   EmitUint8(0x0F);
    566   EmitUint8(0x5A);
    567   EmitXmmRegisterOperand(dst, src);
    568 }
    569 
    570 
    571 void X86Assembler::cvtdq2pd(XmmRegister dst, XmmRegister src) {
    572   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    573   EmitUint8(0xF3);
    574   EmitUint8(0x0F);
    575   EmitUint8(0xE6);
    576   EmitXmmRegisterOperand(dst, src);
    577 }
    578 
    579 
    580 void X86Assembler::comiss(XmmRegister a, XmmRegister b) {
    581   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    582   EmitUint8(0x0F);
    583   EmitUint8(0x2F);
    584   EmitXmmRegisterOperand(a, b);
    585 }
    586 
    587 
    588 void X86Assembler::comisd(XmmRegister a, XmmRegister b) {
    589   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    590   EmitUint8(0x66);
    591   EmitUint8(0x0F);
    592   EmitUint8(0x2F);
    593   EmitXmmRegisterOperand(a, b);
    594 }
    595 
    596 
    597 void X86Assembler::sqrtsd(XmmRegister dst, XmmRegister src) {
    598   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    599   EmitUint8(0xF2);
    600   EmitUint8(0x0F);
    601   EmitUint8(0x51);
    602   EmitXmmRegisterOperand(dst, src);
    603 }
    604 
    605 
    606 void X86Assembler::sqrtss(XmmRegister dst, XmmRegister src) {
    607   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    608   EmitUint8(0xF3);
    609   EmitUint8(0x0F);
    610   EmitUint8(0x51);
    611   EmitXmmRegisterOperand(dst, src);
    612 }
    613 
    614 
    615 void X86Assembler::xorpd(XmmRegister dst, const Address& src) {
    616   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    617   EmitUint8(0x66);
    618   EmitUint8(0x0F);
    619   EmitUint8(0x57);
    620   EmitOperand(dst, src);
    621 }
    622 
    623 
    624 void X86Assembler::xorpd(XmmRegister dst, XmmRegister src) {
    625   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    626   EmitUint8(0x66);
    627   EmitUint8(0x0F);
    628   EmitUint8(0x57);
    629   EmitXmmRegisterOperand(dst, src);
    630 }
    631 
    632 
    633 void X86Assembler::xorps(XmmRegister dst, const Address& src) {
    634   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    635   EmitUint8(0x0F);
    636   EmitUint8(0x57);
    637   EmitOperand(dst, src);
    638 }
    639 
    640 
    641 void X86Assembler::xorps(XmmRegister dst, XmmRegister src) {
    642   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    643   EmitUint8(0x0F);
    644   EmitUint8(0x57);
    645   EmitXmmRegisterOperand(dst, src);
    646 }
    647 
    648 
    649 void X86Assembler::andpd(XmmRegister dst, const Address& src) {
    650   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    651   EmitUint8(0x66);
    652   EmitUint8(0x0F);
    653   EmitUint8(0x54);
    654   EmitOperand(dst, src);
    655 }
    656 
    657 
    658 void X86Assembler::fldl(const Address& src) {
    659   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    660   EmitUint8(0xDD);
    661   EmitOperand(0, src);
    662 }
    663 
    664 
    665 void X86Assembler::fstpl(const Address& dst) {
    666   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    667   EmitUint8(0xDD);
    668   EmitOperand(3, dst);
    669 }
    670 
    671 
    672 void X86Assembler::fnstcw(const Address& dst) {
    673   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    674   EmitUint8(0xD9);
    675   EmitOperand(7, dst);
    676 }
    677 
    678 
    679 void X86Assembler::fldcw(const Address& src) {
    680   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    681   EmitUint8(0xD9);
    682   EmitOperand(5, src);
    683 }
    684 
    685 
    686 void X86Assembler::fistpl(const Address& dst) {
    687   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    688   EmitUint8(0xDF);
    689   EmitOperand(7, dst);
    690 }
    691 
    692 
    693 void X86Assembler::fistps(const Address& dst) {
    694   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    695   EmitUint8(0xDB);
    696   EmitOperand(3, dst);
    697 }
    698 
    699 
    700 void X86Assembler::fildl(const Address& src) {
    701   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    702   EmitUint8(0xDF);
    703   EmitOperand(5, src);
    704 }
    705 
    706 
    707 void X86Assembler::fincstp() {
    708   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    709   EmitUint8(0xD9);
    710   EmitUint8(0xF7);
    711 }
    712 
    713 
    714 void X86Assembler::ffree(const Immediate& index) {
    715   CHECK_LT(index.value(), 7);
    716   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    717   EmitUint8(0xDD);
    718   EmitUint8(0xC0 + index.value());
    719 }
    720 
    721 
    722 void X86Assembler::fsin() {
    723   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    724   EmitUint8(0xD9);
    725   EmitUint8(0xFE);
    726 }
    727 
    728 
    729 void X86Assembler::fcos() {
    730   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    731   EmitUint8(0xD9);
    732   EmitUint8(0xFF);
    733 }
    734 
    735 
    736 void X86Assembler::fptan() {
    737   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    738   EmitUint8(0xD9);
    739   EmitUint8(0xF2);
    740 }
    741 
    742 
    743 void X86Assembler::xchgl(Register dst, Register src) {
    744   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    745   EmitUint8(0x87);
    746   EmitRegisterOperand(dst, src);
    747 }
    748 
    749 void X86Assembler::xchgl(Register reg, const Address& address) {
    750   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    751   EmitUint8(0x87);
    752   EmitOperand(reg, address);
    753 }
    754 
    755 
    756 void X86Assembler::cmpl(Register reg, const Immediate& imm) {
    757   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    758   EmitComplex(7, Operand(reg), imm);
    759 }
    760 
    761 
    762 void X86Assembler::cmpl(Register reg0, Register reg1) {
    763   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    764   EmitUint8(0x3B);
    765   EmitOperand(reg0, Operand(reg1));
    766 }
    767 
    768 
    769 void X86Assembler::cmpl(Register reg, const Address& address) {
    770   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    771   EmitUint8(0x3B);
    772   EmitOperand(reg, address);
    773 }
    774 
    775 
    776 void X86Assembler::addl(Register dst, Register src) {
    777   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    778   EmitUint8(0x03);
    779   EmitRegisterOperand(dst, src);
    780 }
    781 
    782 
    783 void X86Assembler::addl(Register reg, const Address& address) {
    784   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    785   EmitUint8(0x03);
    786   EmitOperand(reg, address);
    787 }
    788 
    789 
    790 void X86Assembler::cmpl(const Address& address, Register reg) {
    791   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    792   EmitUint8(0x39);
    793   EmitOperand(reg, address);
    794 }
    795 
    796 
    797 void X86Assembler::cmpl(const Address& address, const Immediate& imm) {
    798   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    799   EmitComplex(7, address, imm);
    800 }
    801 
    802 
    803 void X86Assembler::testl(Register reg1, Register reg2) {
    804   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    805   EmitUint8(0x85);
    806   EmitRegisterOperand(reg1, reg2);
    807 }
    808 
    809 
    810 void X86Assembler::testl(Register reg, const Immediate& immediate) {
    811   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    812   // For registers that have a byte variant (EAX, EBX, ECX, and EDX)
    813   // we only test the byte register to keep the encoding short.
    814   if (immediate.is_uint8() && reg < 4) {
    815     // Use zero-extended 8-bit immediate.
    816     if (reg == EAX) {
    817       EmitUint8(0xA8);
    818     } else {
    819       EmitUint8(0xF6);
    820       EmitUint8(0xC0 + reg);
    821     }
    822     EmitUint8(immediate.value() & 0xFF);
    823   } else if (reg == EAX) {
    824     // Use short form if the destination is EAX.
    825     EmitUint8(0xA9);
    826     EmitImmediate(immediate);
    827   } else {
    828     EmitUint8(0xF7);
    829     EmitOperand(0, Operand(reg));
    830     EmitImmediate(immediate);
    831   }
    832 }
    833 
    834 
    835 void X86Assembler::andl(Register dst, Register src) {
    836   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    837   EmitUint8(0x23);
    838   EmitOperand(dst, Operand(src));
    839 }
    840 
    841 
    842 void X86Assembler::andl(Register dst, const Immediate& imm) {
    843   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    844   EmitComplex(4, Operand(dst), imm);
    845 }
    846 
    847 
    848 void X86Assembler::orl(Register dst, Register src) {
    849   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    850   EmitUint8(0x0B);
    851   EmitOperand(dst, Operand(src));
    852 }
    853 
    854 
    855 void X86Assembler::orl(Register dst, const Immediate& imm) {
    856   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    857   EmitComplex(1, Operand(dst), imm);
    858 }
    859 
    860 
    861 void X86Assembler::xorl(Register dst, Register src) {
    862   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    863   EmitUint8(0x33);
    864   EmitOperand(dst, Operand(src));
    865 }
    866 
    867 
    868 void X86Assembler::addl(Register reg, const Immediate& imm) {
    869   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    870   EmitComplex(0, Operand(reg), imm);
    871 }
    872 
    873 
    874 void X86Assembler::addl(const Address& address, Register reg) {
    875   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    876   EmitUint8(0x01);
    877   EmitOperand(reg, address);
    878 }
    879 
    880 
    881 void X86Assembler::addl(const Address& address, const Immediate& imm) {
    882   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    883   EmitComplex(0, address, imm);
    884 }
    885 
    886 
    887 void X86Assembler::adcl(Register reg, const Immediate& imm) {
    888   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    889   EmitComplex(2, Operand(reg), imm);
    890 }
    891 
    892 
    893 void X86Assembler::adcl(Register dst, Register src) {
    894   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    895   EmitUint8(0x13);
    896   EmitOperand(dst, Operand(src));
    897 }
    898 
    899 
    900 void X86Assembler::adcl(Register dst, const Address& address) {
    901   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    902   EmitUint8(0x13);
    903   EmitOperand(dst, address);
    904 }
    905 
    906 
    907 void X86Assembler::subl(Register dst, Register src) {
    908   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    909   EmitUint8(0x2B);
    910   EmitOperand(dst, Operand(src));
    911 }
    912 
    913 
    914 void X86Assembler::subl(Register reg, const Immediate& imm) {
    915   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    916   EmitComplex(5, Operand(reg), imm);
    917 }
    918 
    919 
    920 void X86Assembler::subl(Register reg, const Address& address) {
    921   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    922   EmitUint8(0x2B);
    923   EmitOperand(reg, address);
    924 }
    925 
    926 
    927 void X86Assembler::cdq() {
    928   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    929   EmitUint8(0x99);
    930 }
    931 
    932 
    933 void X86Assembler::idivl(Register reg) {
    934   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    935   EmitUint8(0xF7);
    936   EmitUint8(0xF8 | reg);
    937 }
    938 
    939 
    940 void X86Assembler::imull(Register dst, Register src) {
    941   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    942   EmitUint8(0x0F);
    943   EmitUint8(0xAF);
    944   EmitOperand(dst, Operand(src));
    945 }
    946 
    947 
    948 void X86Assembler::imull(Register reg, const Immediate& imm) {
    949   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    950   EmitUint8(0x69);
    951   EmitOperand(reg, Operand(reg));
    952   EmitImmediate(imm);
    953 }
    954 
    955 
    956 void X86Assembler::imull(Register reg, const Address& address) {
    957   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    958   EmitUint8(0x0F);
    959   EmitUint8(0xAF);
    960   EmitOperand(reg, address);
    961 }
    962 
    963 
    964 void X86Assembler::imull(Register reg) {
    965   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    966   EmitUint8(0xF7);
    967   EmitOperand(5, Operand(reg));
    968 }
    969 
    970 
    971 void X86Assembler::imull(const Address& address) {
    972   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    973   EmitUint8(0xF7);
    974   EmitOperand(5, address);
    975 }
    976 
    977 
    978 void X86Assembler::mull(Register reg) {
    979   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    980   EmitUint8(0xF7);
    981   EmitOperand(4, Operand(reg));
    982 }
    983 
    984 
    985 void X86Assembler::mull(const Address& address) {
    986   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    987   EmitUint8(0xF7);
    988   EmitOperand(4, address);
    989 }
    990 
    991 
    992 void X86Assembler::sbbl(Register dst, Register src) {
    993   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
    994   EmitUint8(0x1B);
    995   EmitOperand(dst, Operand(src));
    996 }
    997 
    998 
    999 void X86Assembler::sbbl(Register reg, const Immediate& imm) {
   1000   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   1001   EmitComplex(3, Operand(reg), imm);
   1002 }
   1003 
   1004 
   1005 void X86Assembler::sbbl(Register dst, const Address& address) {
   1006   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   1007   EmitUint8(0x1B);
   1008   EmitOperand(dst, address);
   1009 }
   1010 
   1011 
   1012 void X86Assembler::incl(Register reg) {
   1013   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   1014   EmitUint8(0x40 + reg);
   1015 }
   1016 
   1017 
   1018 void X86Assembler::incl(const Address& address) {
   1019   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   1020   EmitUint8(0xFF);
   1021   EmitOperand(0, address);
   1022 }
   1023 
   1024 
   1025 void X86Assembler::decl(Register reg) {
   1026   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   1027   EmitUint8(0x48 + reg);
   1028 }
   1029 
   1030 
   1031 void X86Assembler::decl(const Address& address) {
   1032   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   1033   EmitUint8(0xFF);
   1034   EmitOperand(1, address);
   1035 }
   1036 
   1037 
   1038 void X86Assembler::shll(Register reg, const Immediate& imm) {
   1039   EmitGenericShift(4, reg, imm);
   1040 }
   1041 
   1042 
   1043 void X86Assembler::shll(Register operand, Register shifter) {
   1044   EmitGenericShift(4, operand, shifter);
   1045 }
   1046 
   1047 
   1048 void X86Assembler::shrl(Register reg, const Immediate& imm) {
   1049   EmitGenericShift(5, reg, imm);
   1050 }
   1051 
   1052 
   1053 void X86Assembler::shrl(Register operand, Register shifter) {
   1054   EmitGenericShift(5, operand, shifter);
   1055 }
   1056 
   1057 
   1058 void X86Assembler::sarl(Register reg, const Immediate& imm) {
   1059   EmitGenericShift(7, reg, imm);
   1060 }
   1061 
   1062 
   1063 void X86Assembler::sarl(Register operand, Register shifter) {
   1064   EmitGenericShift(7, operand, shifter);
   1065 }
   1066 
   1067 
   1068 void X86Assembler::shld(Register dst, Register src) {
   1069   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   1070   EmitUint8(0x0F);
   1071   EmitUint8(0xA5);
   1072   EmitRegisterOperand(src, dst);
   1073 }
   1074 
   1075 
   1076 void X86Assembler::negl(Register reg) {
   1077   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   1078   EmitUint8(0xF7);
   1079   EmitOperand(3, Operand(reg));
   1080 }
   1081 
   1082 
   1083 void X86Assembler::notl(Register reg) {
   1084   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   1085   EmitUint8(0xF7);
   1086   EmitUint8(0xD0 | reg);
   1087 }
   1088 
   1089 
   1090 void X86Assembler::enter(const Immediate& imm) {
   1091   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   1092   EmitUint8(0xC8);
   1093   CHECK(imm.is_uint16());
   1094   EmitUint8(imm.value() & 0xFF);
   1095   EmitUint8((imm.value() >> 8) & 0xFF);
   1096   EmitUint8(0x00);
   1097 }
   1098 
   1099 
   1100 void X86Assembler::leave() {
   1101   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   1102   EmitUint8(0xC9);
   1103 }
   1104 
   1105 
   1106 void X86Assembler::ret() {
   1107   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   1108   EmitUint8(0xC3);
   1109 }
   1110 
   1111 
   1112 void X86Assembler::ret(const Immediate& imm) {
   1113   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   1114   EmitUint8(0xC2);
   1115   CHECK(imm.is_uint16());
   1116   EmitUint8(imm.value() & 0xFF);
   1117   EmitUint8((imm.value() >> 8) & 0xFF);
   1118 }
   1119 
   1120 
   1121 
   1122 void X86Assembler::nop() {
   1123   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   1124   EmitUint8(0x90);
   1125 }
   1126 
   1127 
   1128 void X86Assembler::int3() {
   1129   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   1130   EmitUint8(0xCC);
   1131 }
   1132 
   1133 
   1134 void X86Assembler::hlt() {
   1135   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   1136   EmitUint8(0xF4);
   1137 }
   1138 
   1139 
   1140 void X86Assembler::j(Condition condition, Label* label) {
   1141   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   1142   if (label->IsBound()) {
   1143     static const int kShortSize = 2;
   1144     static const int kLongSize = 6;
   1145     int offset = label->Position() - buffer_.Size();
   1146     CHECK_LE(offset, 0);
   1147     if (IsInt(8, offset - kShortSize)) {
   1148       EmitUint8(0x70 + condition);
   1149       EmitUint8((offset - kShortSize) & 0xFF);
   1150     } else {
   1151       EmitUint8(0x0F);
   1152       EmitUint8(0x80 + condition);
   1153       EmitInt32(offset - kLongSize);
   1154     }
   1155   } else {
   1156     EmitUint8(0x0F);
   1157     EmitUint8(0x80 + condition);
   1158     EmitLabelLink(label);
   1159   }
   1160 }
   1161 
   1162 
   1163 void X86Assembler::jmp(Register reg) {
   1164   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   1165   EmitUint8(0xFF);
   1166   EmitRegisterOperand(4, reg);
   1167 }
   1168 
   1169 void X86Assembler::jmp(const Address& address) {
   1170   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   1171   EmitUint8(0xFF);
   1172   EmitOperand(4, address);
   1173 }
   1174 
   1175 void X86Assembler::jmp(Label* label) {
   1176   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   1177   if (label->IsBound()) {
   1178     static const int kShortSize = 2;
   1179     static const int kLongSize = 5;
   1180     int offset = label->Position() - buffer_.Size();
   1181     CHECK_LE(offset, 0);
   1182     if (IsInt(8, offset - kShortSize)) {
   1183       EmitUint8(0xEB);
   1184       EmitUint8((offset - kShortSize) & 0xFF);
   1185     } else {
   1186       EmitUint8(0xE9);
   1187       EmitInt32(offset - kLongSize);
   1188     }
   1189   } else {
   1190     EmitUint8(0xE9);
   1191     EmitLabelLink(label);
   1192   }
   1193 }
   1194 
   1195 
   1196 X86Assembler* X86Assembler::lock() {
   1197   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   1198   EmitUint8(0xF0);
   1199   return this;
   1200 }
   1201 
   1202 
   1203 void X86Assembler::cmpxchgl(const Address& address, Register reg) {
   1204   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   1205   EmitUint8(0x0F);
   1206   EmitUint8(0xB1);
   1207   EmitOperand(reg, address);
   1208 }
   1209 
   1210 void X86Assembler::mfence() {
   1211   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   1212   EmitUint8(0x0F);
   1213   EmitUint8(0xAE);
   1214   EmitUint8(0xF0);
   1215 }
   1216 
   1217 X86Assembler* X86Assembler::fs() {
   1218   // TODO: fs is a prefix and not an instruction
   1219   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   1220   EmitUint8(0x64);
   1221   return this;
   1222 }
   1223 
   1224 void X86Assembler::AddImmediate(Register reg, const Immediate& imm) {
   1225   int value = imm.value();
   1226   if (value > 0) {
   1227     if (value == 1) {
   1228       incl(reg);
   1229     } else if (value != 0) {
   1230       addl(reg, imm);
   1231     }
   1232   } else if (value < 0) {
   1233     value = -value;
   1234     if (value == 1) {
   1235       decl(reg);
   1236     } else if (value != 0) {
   1237       subl(reg, Immediate(value));
   1238     }
   1239   }
   1240 }
   1241 
   1242 
   1243 void X86Assembler::LoadDoubleConstant(XmmRegister dst, double value) {
   1244   // TODO: Need to have a code constants table.
   1245   int64_t constant = bit_cast<int64_t, double>(value);
   1246   pushl(Immediate(High32Bits(constant)));
   1247   pushl(Immediate(Low32Bits(constant)));
   1248   movsd(dst, Address(ESP, 0));
   1249   addl(ESP, Immediate(2 * kWordSize));
   1250 }
   1251 
   1252 
   1253 void X86Assembler::FloatNegate(XmmRegister f) {
   1254   static const struct {
   1255     uint32_t a;
   1256     uint32_t b;
   1257     uint32_t c;
   1258     uint32_t d;
   1259   } float_negate_constant __attribute__((aligned(16))) =
   1260       { 0x80000000, 0x00000000, 0x80000000, 0x00000000 };
   1261   xorps(f, Address::Absolute(reinterpret_cast<uword>(&float_negate_constant)));
   1262 }
   1263 
   1264 
   1265 void X86Assembler::DoubleNegate(XmmRegister d) {
   1266   static const struct {
   1267     uint64_t a;
   1268     uint64_t b;
   1269   } double_negate_constant __attribute__((aligned(16))) =
   1270       {0x8000000000000000LL, 0x8000000000000000LL};
   1271   xorpd(d, Address::Absolute(reinterpret_cast<uword>(&double_negate_constant)));
   1272 }
   1273 
   1274 
   1275 void X86Assembler::DoubleAbs(XmmRegister reg) {
   1276   static const struct {
   1277     uint64_t a;
   1278     uint64_t b;
   1279   } double_abs_constant __attribute__((aligned(16))) =
   1280       {0x7FFFFFFFFFFFFFFFLL, 0x7FFFFFFFFFFFFFFFLL};
   1281   andpd(reg, Address::Absolute(reinterpret_cast<uword>(&double_abs_constant)));
   1282 }
   1283 
   1284 
   1285 void X86Assembler::Align(int alignment, int offset) {
   1286   CHECK(IsPowerOfTwo(alignment));
   1287   // Emit nop instruction until the real position is aligned.
   1288   while (((offset + buffer_.GetPosition()) & (alignment-1)) != 0) {
   1289     nop();
   1290   }
   1291 }
   1292 
   1293 
   1294 void X86Assembler::Bind(Label* label) {
   1295   int bound = buffer_.Size();
   1296   CHECK(!label->IsBound());  // Labels can only be bound once.
   1297   while (label->IsLinked()) {
   1298     int position = label->LinkPosition();
   1299     int next = buffer_.Load<int32_t>(position);
   1300     buffer_.Store<int32_t>(position, bound - (position + 4));
   1301     label->position_ = next;
   1302   }
   1303   label->BindTo(bound);
   1304 }
   1305 
   1306 
   1307 void X86Assembler::Stop(const char* message) {
   1308   // Emit the message address as immediate operand in the test rax instruction,
   1309   // followed by the int3 instruction.
   1310   // Execution can be resumed with the 'cont' command in gdb.
   1311   testl(EAX, Immediate(reinterpret_cast<int32_t>(message)));
   1312   int3();
   1313 }
   1314 
   1315 
   1316 void X86Assembler::EmitOperand(int reg_or_opcode, const Operand& operand) {
   1317   CHECK_GE(reg_or_opcode, 0);
   1318   CHECK_LT(reg_or_opcode, 8);
   1319   const int length = operand.length_;
   1320   CHECK_GT(length, 0);
   1321   // Emit the ModRM byte updated with the given reg value.
   1322   CHECK_EQ(operand.encoding_[0] & 0x38, 0);
   1323   EmitUint8(operand.encoding_[0] + (reg_or_opcode << 3));
   1324   // Emit the rest of the encoded operand.
   1325   for (int i = 1; i < length; i++) {
   1326     EmitUint8(operand.encoding_[i]);
   1327   }
   1328 }
   1329 
   1330 
   1331 void X86Assembler::EmitImmediate(const Immediate& imm) {
   1332   EmitInt32(imm.value());
   1333 }
   1334 
   1335 
   1336 void X86Assembler::EmitComplex(int reg_or_opcode,
   1337                                const Operand& operand,
   1338                                const Immediate& immediate) {
   1339   CHECK_GE(reg_or_opcode, 0);
   1340   CHECK_LT(reg_or_opcode, 8);
   1341   if (immediate.is_int8()) {
   1342     // Use sign-extended 8-bit immediate.
   1343     EmitUint8(0x83);
   1344     EmitOperand(reg_or_opcode, operand);
   1345     EmitUint8(immediate.value() & 0xFF);
   1346   } else if (operand.IsRegister(EAX)) {
   1347     // Use short form if the destination is eax.
   1348     EmitUint8(0x05 + (reg_or_opcode << 3));
   1349     EmitImmediate(immediate);
   1350   } else {
   1351     EmitUint8(0x81);
   1352     EmitOperand(reg_or_opcode, operand);
   1353     EmitImmediate(immediate);
   1354   }
   1355 }
   1356 
   1357 
   1358 void X86Assembler::EmitLabel(Label* label, int instruction_size) {
   1359   if (label->IsBound()) {
   1360     int offset = label->Position() - buffer_.Size();
   1361     CHECK_LE(offset, 0);
   1362     EmitInt32(offset - instruction_size);
   1363   } else {
   1364     EmitLabelLink(label);
   1365   }
   1366 }
   1367 
   1368 
   1369 void X86Assembler::EmitLabelLink(Label* label) {
   1370   CHECK(!label->IsBound());
   1371   int position = buffer_.Size();
   1372   EmitInt32(label->position_);
   1373   label->LinkTo(position);
   1374 }
   1375 
   1376 
   1377 void X86Assembler::EmitGenericShift(int reg_or_opcode,
   1378                                     Register reg,
   1379                                     const Immediate& imm) {
   1380   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   1381   CHECK(imm.is_int8());
   1382   if (imm.value() == 1) {
   1383     EmitUint8(0xD1);
   1384     EmitOperand(reg_or_opcode, Operand(reg));
   1385   } else {
   1386     EmitUint8(0xC1);
   1387     EmitOperand(reg_or_opcode, Operand(reg));
   1388     EmitUint8(imm.value() & 0xFF);
   1389   }
   1390 }
   1391 
   1392 
   1393 void X86Assembler::EmitGenericShift(int reg_or_opcode,
   1394                                     Register operand,
   1395                                     Register shifter) {
   1396   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   1397   CHECK_EQ(shifter, ECX);
   1398   EmitUint8(0xD3);
   1399   EmitOperand(reg_or_opcode, Operand(operand));
   1400 }
   1401 
   1402 void X86Assembler::BuildFrame(size_t frame_size, ManagedRegister method_reg,
   1403                               const std::vector<ManagedRegister>& spill_regs,
   1404                               const std::vector<ManagedRegister>& entry_spills) {
   1405   CHECK_ALIGNED(frame_size, kStackAlignment);
   1406   for (int i = spill_regs.size() - 1; i >= 0; --i) {
   1407     pushl(spill_regs.at(i).AsX86().AsCpuRegister());
   1408   }
   1409   // return address then method on stack
   1410   addl(ESP, Immediate(-frame_size + (spill_regs.size() * kPointerSize) +
   1411                       kPointerSize /*method*/ + kPointerSize /*return address*/));
   1412   pushl(method_reg.AsX86().AsCpuRegister());
   1413   for (size_t i = 0; i < entry_spills.size(); ++i) {
   1414     movl(Address(ESP, frame_size + kPointerSize + (i * kPointerSize)),
   1415          entry_spills.at(i).AsX86().AsCpuRegister());
   1416   }
   1417 }
   1418 
   1419 void X86Assembler::RemoveFrame(size_t frame_size,
   1420                             const std::vector<ManagedRegister>& spill_regs) {
   1421   CHECK_ALIGNED(frame_size, kStackAlignment);
   1422   addl(ESP, Immediate(frame_size - (spill_regs.size() * kPointerSize) - kPointerSize));
   1423   for (size_t i = 0; i < spill_regs.size(); ++i) {
   1424     popl(spill_regs.at(i).AsX86().AsCpuRegister());
   1425   }
   1426   ret();
   1427 }
   1428 
   1429 void X86Assembler::IncreaseFrameSize(size_t adjust) {
   1430   CHECK_ALIGNED(adjust, kStackAlignment);
   1431   addl(ESP, Immediate(-adjust));
   1432 }
   1433 
   1434 void X86Assembler::DecreaseFrameSize(size_t adjust) {
   1435   CHECK_ALIGNED(adjust, kStackAlignment);
   1436   addl(ESP, Immediate(adjust));
   1437 }
   1438 
   1439 void X86Assembler::Store(FrameOffset offs, ManagedRegister msrc, size_t size) {
   1440   X86ManagedRegister src = msrc.AsX86();
   1441   if (src.IsNoRegister()) {
   1442     CHECK_EQ(0u, size);
   1443   } else if (src.IsCpuRegister()) {
   1444     CHECK_EQ(4u, size);
   1445     movl(Address(ESP, offs), src.AsCpuRegister());
   1446   } else if (src.IsRegisterPair()) {
   1447     CHECK_EQ(8u, size);
   1448     movl(Address(ESP, offs), src.AsRegisterPairLow());
   1449     movl(Address(ESP, FrameOffset(offs.Int32Value()+4)),
   1450          src.AsRegisterPairHigh());
   1451   } else if (src.IsX87Register()) {
   1452     if (size == 4) {
   1453       fstps(Address(ESP, offs));
   1454     } else {
   1455       fstpl(Address(ESP, offs));
   1456     }
   1457   } else {
   1458     CHECK(src.IsXmmRegister());
   1459     if (size == 4) {
   1460       movss(Address(ESP, offs), src.AsXmmRegister());
   1461     } else {
   1462       movsd(Address(ESP, offs), src.AsXmmRegister());
   1463     }
   1464   }
   1465 }
   1466 
   1467 void X86Assembler::StoreRef(FrameOffset dest, ManagedRegister msrc) {
   1468   X86ManagedRegister src = msrc.AsX86();
   1469   CHECK(src.IsCpuRegister());
   1470   movl(Address(ESP, dest), src.AsCpuRegister());
   1471 }
   1472 
   1473 void X86Assembler::StoreRawPtr(FrameOffset dest, ManagedRegister msrc) {
   1474   X86ManagedRegister src = msrc.AsX86();
   1475   CHECK(src.IsCpuRegister());
   1476   movl(Address(ESP, dest), src.AsCpuRegister());
   1477 }
   1478 
   1479 void X86Assembler::StoreImmediateToFrame(FrameOffset dest, uint32_t imm,
   1480                                          ManagedRegister) {
   1481   movl(Address(ESP, dest), Immediate(imm));
   1482 }
   1483 
   1484 void X86Assembler::StoreImmediateToThread(ThreadOffset dest, uint32_t imm,
   1485                                           ManagedRegister) {
   1486   fs()->movl(Address::Absolute(dest), Immediate(imm));
   1487 }
   1488 
   1489 void X86Assembler::StoreStackOffsetToThread(ThreadOffset thr_offs,
   1490                                             FrameOffset fr_offs,
   1491                                             ManagedRegister mscratch) {
   1492   X86ManagedRegister scratch = mscratch.AsX86();
   1493   CHECK(scratch.IsCpuRegister());
   1494   leal(scratch.AsCpuRegister(), Address(ESP, fr_offs));
   1495   fs()->movl(Address::Absolute(thr_offs), scratch.AsCpuRegister());
   1496 }
   1497 
   1498 void X86Assembler::StoreStackPointerToThread(ThreadOffset thr_offs) {
   1499   fs()->movl(Address::Absolute(thr_offs), ESP);
   1500 }
   1501 
   1502 void X86Assembler::StoreLabelToThread(ThreadOffset thr_offs, Label* lbl) {
   1503   fs()->movl(Address::Absolute(thr_offs), lbl);
   1504 }
   1505 
   1506 void X86Assembler::StoreSpanning(FrameOffset /*dst*/, ManagedRegister /*src*/,
   1507                                  FrameOffset /*in_off*/, ManagedRegister /*scratch*/) {
   1508   UNIMPLEMENTED(FATAL);  // this case only currently exists for ARM
   1509 }
   1510 
   1511 void X86Assembler::Load(ManagedRegister mdest, FrameOffset src, size_t size) {
   1512   X86ManagedRegister dest = mdest.AsX86();
   1513   if (dest.IsNoRegister()) {
   1514     CHECK_EQ(0u, size);
   1515   } else if (dest.IsCpuRegister()) {
   1516     CHECK_EQ(4u, size);
   1517     movl(dest.AsCpuRegister(), Address(ESP, src));
   1518   } else if (dest.IsRegisterPair()) {
   1519     CHECK_EQ(8u, size);
   1520     movl(dest.AsRegisterPairLow(), Address(ESP, src));
   1521     movl(dest.AsRegisterPairHigh(), Address(ESP, FrameOffset(src.Int32Value()+4)));
   1522   } else if (dest.IsX87Register()) {
   1523     if (size == 4) {
   1524       flds(Address(ESP, src));
   1525     } else {
   1526       fldl(Address(ESP, src));
   1527     }
   1528   } else {
   1529     CHECK(dest.IsXmmRegister());
   1530     if (size == 4) {
   1531       movss(dest.AsXmmRegister(), Address(ESP, src));
   1532     } else {
   1533       movsd(dest.AsXmmRegister(), Address(ESP, src));
   1534     }
   1535   }
   1536 }
   1537 
   1538 void X86Assembler::Load(ManagedRegister mdest, ThreadOffset src, size_t size) {
   1539   X86ManagedRegister dest = mdest.AsX86();
   1540   if (dest.IsNoRegister()) {
   1541     CHECK_EQ(0u, size);
   1542   } else if (dest.IsCpuRegister()) {
   1543     CHECK_EQ(4u, size);
   1544     fs()->movl(dest.AsCpuRegister(), Address::Absolute(src));
   1545   } else if (dest.IsRegisterPair()) {
   1546     CHECK_EQ(8u, size);
   1547     fs()->movl(dest.AsRegisterPairLow(), Address::Absolute(src));
   1548     fs()->movl(dest.AsRegisterPairHigh(), Address::Absolute(ThreadOffset(src.Int32Value()+4)));
   1549   } else if (dest.IsX87Register()) {
   1550     if (size == 4) {
   1551       fs()->flds(Address::Absolute(src));
   1552     } else {
   1553       fs()->fldl(Address::Absolute(src));
   1554     }
   1555   } else {
   1556     CHECK(dest.IsXmmRegister());
   1557     if (size == 4) {
   1558       fs()->movss(dest.AsXmmRegister(), Address::Absolute(src));
   1559     } else {
   1560       fs()->movsd(dest.AsXmmRegister(), Address::Absolute(src));
   1561     }
   1562   }
   1563 }
   1564 
   1565 void X86Assembler::LoadRef(ManagedRegister mdest, FrameOffset  src) {
   1566   X86ManagedRegister dest = mdest.AsX86();
   1567   CHECK(dest.IsCpuRegister());
   1568   movl(dest.AsCpuRegister(), Address(ESP, src));
   1569 }
   1570 
   1571 void X86Assembler::LoadRef(ManagedRegister mdest, ManagedRegister base,
   1572                            MemberOffset offs) {
   1573   X86ManagedRegister dest = mdest.AsX86();
   1574   CHECK(dest.IsCpuRegister() && dest.IsCpuRegister());
   1575   movl(dest.AsCpuRegister(), Address(base.AsX86().AsCpuRegister(), offs));
   1576 }
   1577 
   1578 void X86Assembler::LoadRawPtr(ManagedRegister mdest, ManagedRegister base,
   1579                               Offset offs) {
   1580   X86ManagedRegister dest = mdest.AsX86();
   1581   CHECK(dest.IsCpuRegister() && dest.IsCpuRegister());
   1582   movl(dest.AsCpuRegister(), Address(base.AsX86().AsCpuRegister(), offs));
   1583 }
   1584 
   1585 void X86Assembler::LoadRawPtrFromThread(ManagedRegister mdest,
   1586                                         ThreadOffset offs) {
   1587   X86ManagedRegister dest = mdest.AsX86();
   1588   CHECK(dest.IsCpuRegister());
   1589   fs()->movl(dest.AsCpuRegister(), Address::Absolute(offs));
   1590 }
   1591 
   1592 void X86Assembler::SignExtend(ManagedRegister mreg, size_t size) {
   1593   X86ManagedRegister reg = mreg.AsX86();
   1594   CHECK(size == 1 || size == 2) << size;
   1595   CHECK(reg.IsCpuRegister()) << reg;
   1596   if (size == 1) {
   1597     movsxb(reg.AsCpuRegister(), reg.AsByteRegister());
   1598   } else {
   1599     movsxw(reg.AsCpuRegister(), reg.AsCpuRegister());
   1600   }
   1601 }
   1602 
   1603 void X86Assembler::ZeroExtend(ManagedRegister mreg, size_t size) {
   1604   X86ManagedRegister reg = mreg.AsX86();
   1605   CHECK(size == 1 || size == 2) << size;
   1606   CHECK(reg.IsCpuRegister()) << reg;
   1607   if (size == 1) {
   1608     movzxb(reg.AsCpuRegister(), reg.AsByteRegister());
   1609   } else {
   1610     movzxw(reg.AsCpuRegister(), reg.AsCpuRegister());
   1611   }
   1612 }
   1613 
   1614 void X86Assembler::Move(ManagedRegister mdest, ManagedRegister msrc, size_t size) {
   1615   X86ManagedRegister dest = mdest.AsX86();
   1616   X86ManagedRegister src = msrc.AsX86();
   1617   if (!dest.Equals(src)) {
   1618     if (dest.IsCpuRegister() && src.IsCpuRegister()) {
   1619       movl(dest.AsCpuRegister(), src.AsCpuRegister());
   1620     } else if (src.IsX87Register() && dest.IsXmmRegister()) {
   1621       // Pass via stack and pop X87 register
   1622       subl(ESP, Immediate(16));
   1623       if (size == 4) {
   1624         CHECK_EQ(src.AsX87Register(), ST0);
   1625         fstps(Address(ESP, 0));
   1626         movss(dest.AsXmmRegister(), Address(ESP, 0));
   1627       } else {
   1628         CHECK_EQ(src.AsX87Register(), ST0);
   1629         fstpl(Address(ESP, 0));
   1630         movsd(dest.AsXmmRegister(), Address(ESP, 0));
   1631       }
   1632       addl(ESP, Immediate(16));
   1633     } else {
   1634       // TODO: x87, SSE
   1635       UNIMPLEMENTED(FATAL) << ": Move " << dest << ", " << src;
   1636     }
   1637   }
   1638 }
   1639 
   1640 void X86Assembler::CopyRef(FrameOffset dest, FrameOffset src,
   1641                            ManagedRegister mscratch) {
   1642   X86ManagedRegister scratch = mscratch.AsX86();
   1643   CHECK(scratch.IsCpuRegister());
   1644   movl(scratch.AsCpuRegister(), Address(ESP, src));
   1645   movl(Address(ESP, dest), scratch.AsCpuRegister());
   1646 }
   1647 
   1648 void X86Assembler::CopyRawPtrFromThread(FrameOffset fr_offs,
   1649                                         ThreadOffset thr_offs,
   1650                                         ManagedRegister mscratch) {
   1651   X86ManagedRegister scratch = mscratch.AsX86();
   1652   CHECK(scratch.IsCpuRegister());
   1653   fs()->movl(scratch.AsCpuRegister(), Address::Absolute(thr_offs));
   1654   Store(fr_offs, scratch, 4);
   1655 }
   1656 
   1657 void X86Assembler::CopyRawPtrToThread(ThreadOffset thr_offs,
   1658                                       FrameOffset fr_offs,
   1659                                       ManagedRegister mscratch) {
   1660   X86ManagedRegister scratch = mscratch.AsX86();
   1661   CHECK(scratch.IsCpuRegister());
   1662   Load(scratch, fr_offs, 4);
   1663   fs()->movl(Address::Absolute(thr_offs), scratch.AsCpuRegister());
   1664 }
   1665 
   1666 void X86Assembler::Copy(FrameOffset dest, FrameOffset src,
   1667                         ManagedRegister mscratch,
   1668                         size_t size) {
   1669   X86ManagedRegister scratch = mscratch.AsX86();
   1670   if (scratch.IsCpuRegister() && size == 8) {
   1671     Load(scratch, src, 4);
   1672     Store(dest, scratch, 4);
   1673     Load(scratch, FrameOffset(src.Int32Value() + 4), 4);
   1674     Store(FrameOffset(dest.Int32Value() + 4), scratch, 4);
   1675   } else {
   1676     Load(scratch, src, size);
   1677     Store(dest, scratch, size);
   1678   }
   1679 }
   1680 
   1681 void X86Assembler::Copy(FrameOffset /*dst*/, ManagedRegister /*src_base*/, Offset /*src_offset*/,
   1682                         ManagedRegister /*scratch*/, size_t /*size*/) {
   1683   UNIMPLEMENTED(FATAL);
   1684 }
   1685 
   1686 void X86Assembler::Copy(ManagedRegister dest_base, Offset dest_offset, FrameOffset src,
   1687                         ManagedRegister scratch, size_t size) {
   1688   CHECK(scratch.IsNoRegister());
   1689   CHECK_EQ(size, 4u);
   1690   pushl(Address(ESP, src));
   1691   popl(Address(dest_base.AsX86().AsCpuRegister(), dest_offset));
   1692 }
   1693 
   1694 void X86Assembler::Copy(FrameOffset dest, FrameOffset src_base, Offset src_offset,
   1695                         ManagedRegister mscratch, size_t size) {
   1696   Register scratch = mscratch.AsX86().AsCpuRegister();
   1697   CHECK_EQ(size, 4u);
   1698   movl(scratch, Address(ESP, src_base));
   1699   movl(scratch, Address(scratch, src_offset));
   1700   movl(Address(ESP, dest), scratch);
   1701 }
   1702 
   1703 void X86Assembler::Copy(ManagedRegister dest, Offset dest_offset,
   1704                         ManagedRegister src, Offset src_offset,
   1705                         ManagedRegister scratch, size_t size) {
   1706   CHECK_EQ(size, 4u);
   1707   CHECK(scratch.IsNoRegister());
   1708   pushl(Address(src.AsX86().AsCpuRegister(), src_offset));
   1709   popl(Address(dest.AsX86().AsCpuRegister(), dest_offset));
   1710 }
   1711 
   1712 void X86Assembler::Copy(FrameOffset dest, Offset dest_offset, FrameOffset src, Offset src_offset,
   1713                         ManagedRegister mscratch, size_t size) {
   1714   Register scratch = mscratch.AsX86().AsCpuRegister();
   1715   CHECK_EQ(size, 4u);
   1716   CHECK_EQ(dest.Int32Value(), src.Int32Value());
   1717   movl(scratch, Address(ESP, src));
   1718   pushl(Address(scratch, src_offset));
   1719   popl(Address(scratch, dest_offset));
   1720 }
   1721 
   1722 void X86Assembler::MemoryBarrier(ManagedRegister) {
   1723 #if ANDROID_SMP != 0
   1724   mfence();
   1725 #endif
   1726 }
   1727 
   1728 void X86Assembler::CreateSirtEntry(ManagedRegister mout_reg,
   1729                                    FrameOffset sirt_offset,
   1730                                    ManagedRegister min_reg, bool null_allowed) {
   1731   X86ManagedRegister out_reg = mout_reg.AsX86();
   1732   X86ManagedRegister in_reg = min_reg.AsX86();
   1733   CHECK(in_reg.IsCpuRegister());
   1734   CHECK(out_reg.IsCpuRegister());
   1735   VerifyObject(in_reg, null_allowed);
   1736   if (null_allowed) {
   1737     Label null_arg;
   1738     if (!out_reg.Equals(in_reg)) {
   1739       xorl(out_reg.AsCpuRegister(), out_reg.AsCpuRegister());
   1740     }
   1741     testl(in_reg.AsCpuRegister(), in_reg.AsCpuRegister());
   1742     j(kZero, &null_arg);
   1743     leal(out_reg.AsCpuRegister(), Address(ESP, sirt_offset));
   1744     Bind(&null_arg);
   1745   } else {
   1746     leal(out_reg.AsCpuRegister(), Address(ESP, sirt_offset));
   1747   }
   1748 }
   1749 
   1750 void X86Assembler::CreateSirtEntry(FrameOffset out_off,
   1751                                    FrameOffset sirt_offset,
   1752                                    ManagedRegister mscratch,
   1753                                    bool null_allowed) {
   1754   X86ManagedRegister scratch = mscratch.AsX86();
   1755   CHECK(scratch.IsCpuRegister());
   1756   if (null_allowed) {
   1757     Label null_arg;
   1758     movl(scratch.AsCpuRegister(), Address(ESP, sirt_offset));
   1759     testl(scratch.AsCpuRegister(), scratch.AsCpuRegister());
   1760     j(kZero, &null_arg);
   1761     leal(scratch.AsCpuRegister(), Address(ESP, sirt_offset));
   1762     Bind(&null_arg);
   1763   } else {
   1764     leal(scratch.AsCpuRegister(), Address(ESP, sirt_offset));
   1765   }
   1766   Store(out_off, scratch, 4);
   1767 }
   1768 
   1769 // Given a SIRT entry, load the associated reference.
   1770 void X86Assembler::LoadReferenceFromSirt(ManagedRegister mout_reg,
   1771                                          ManagedRegister min_reg) {
   1772   X86ManagedRegister out_reg = mout_reg.AsX86();
   1773   X86ManagedRegister in_reg = min_reg.AsX86();
   1774   CHECK(out_reg.IsCpuRegister());
   1775   CHECK(in_reg.IsCpuRegister());
   1776   Label null_arg;
   1777   if (!out_reg.Equals(in_reg)) {
   1778     xorl(out_reg.AsCpuRegister(), out_reg.AsCpuRegister());
   1779   }
   1780   testl(in_reg.AsCpuRegister(), in_reg.AsCpuRegister());
   1781   j(kZero, &null_arg);
   1782   movl(out_reg.AsCpuRegister(), Address(in_reg.AsCpuRegister(), 0));
   1783   Bind(&null_arg);
   1784 }
   1785 
   1786 void X86Assembler::VerifyObject(ManagedRegister /*src*/, bool /*could_be_null*/) {
   1787   // TODO: not validating references
   1788 }
   1789 
   1790 void X86Assembler::VerifyObject(FrameOffset /*src*/, bool /*could_be_null*/) {
   1791   // TODO: not validating references
   1792 }
   1793 
   1794 void X86Assembler::Call(ManagedRegister mbase, Offset offset, ManagedRegister) {
   1795   X86ManagedRegister base = mbase.AsX86();
   1796   CHECK(base.IsCpuRegister());
   1797   call(Address(base.AsCpuRegister(), offset.Int32Value()));
   1798   // TODO: place reference map on call
   1799 }
   1800 
   1801 void X86Assembler::Call(FrameOffset base, Offset offset, ManagedRegister mscratch) {
   1802   Register scratch = mscratch.AsX86().AsCpuRegister();
   1803   movl(scratch, Address(ESP, base));
   1804   call(Address(scratch, offset));
   1805 }
   1806 
   1807 void X86Assembler::Call(ThreadOffset offset, ManagedRegister /*mscratch*/) {
   1808   fs()->call(Address::Absolute(offset));
   1809 }
   1810 
   1811 void X86Assembler::GetCurrentThread(ManagedRegister tr) {
   1812   fs()->movl(tr.AsX86().AsCpuRegister(),
   1813              Address::Absolute(Thread::SelfOffset()));
   1814 }
   1815 
   1816 void X86Assembler::GetCurrentThread(FrameOffset offset,
   1817                                     ManagedRegister mscratch) {
   1818   X86ManagedRegister scratch = mscratch.AsX86();
   1819   fs()->movl(scratch.AsCpuRegister(), Address::Absolute(Thread::SelfOffset()));
   1820   movl(Address(ESP, offset), scratch.AsCpuRegister());
   1821 }
   1822 
   1823 void X86Assembler::ExceptionPoll(ManagedRegister /*scratch*/, size_t stack_adjust) {
   1824   X86ExceptionSlowPath* slow = new X86ExceptionSlowPath(stack_adjust);
   1825   buffer_.EnqueueSlowPath(slow);
   1826   fs()->cmpl(Address::Absolute(Thread::ExceptionOffset()), Immediate(0));
   1827   j(kNotEqual, slow->Entry());
   1828 }
   1829 
   1830 void X86ExceptionSlowPath::Emit(Assembler *sasm) {
   1831   X86Assembler* sp_asm = down_cast<X86Assembler*>(sasm);
   1832 #define __ sp_asm->
   1833   __ Bind(&entry_);
   1834   // Note: the return value is dead
   1835   if (stack_adjust_ != 0) {  // Fix up the frame.
   1836     __ DecreaseFrameSize(stack_adjust_);
   1837   }
   1838   // Pass exception as argument in EAX
   1839   __ fs()->movl(EAX, Address::Absolute(Thread::ExceptionOffset()));
   1840   __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(pDeliverException)));
   1841   // this call should never return
   1842   __ int3();
   1843 #undef __
   1844 }
   1845 
   1846 }  // namespace x86
   1847 }  // namespace art
   1848