assembler.cpp

Go to the documentation of this file.
00001 /* Copyright 1994 - 1996, LongView Technologies L.L.C. $Revision: 1.37 $ */
00002 /* Copyright (c) 2006, Sun Microsystems, Inc.
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 
00006 following conditions are met:
00007 
00008     * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
00009     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 
00010           disclaimer in the documentation and/or other materials provided with the distribution.
00011     * Neither the name of Sun Microsystems nor the names of its contributors may be used to endorse or promote products derived 
00012           from this software without specific prior written permission.
00013 
00014 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 
00015 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
00016 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
00017 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
00018 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
00019 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
00020 
00021 
00022 */
00023 
00024 #include "incls/_precompiled.incl"
00025 #include "incls/_assembler.cpp.incl"
00026 
00027 
00028 // A Displacement describes the 32bit immediate field of an instruction which
00029 // may be used together with a Label in order to refer to a yet unknown code
00030 // position. Displacements stored in the instruction stream are used to describe
00031 // the instruction and to chain a list of instructions using the same Label.
00032 // A Displacement contains 3 different fields:
00033 //
00034 // next field: position of next displacement in the chain (0 = end of list)
00035 // type field: instruction type
00036 // info field: instruction specific information
00037 //
00038 // A next value of null (0) indicates the end of a chain (note that there can
00039 // be no displacement at position zero, because there is always at least one
00040 // instruction byte before the displacement).
00041 //
00042 // Displacement _data field layout
00043 //
00044 // |31....10|9......8|7......0|
00045 // [  next  |  type  |  info  ]
00046 
00047 class Displacement : public ValueObj {
00048  private:
00049   int _data;
00050 
00051   enum Layout {
00052     info_size   =  IC_Info::number_of_flags,
00053     type_size   =  2,
00054     next_size   = 32 - (type_size + info_size),
00055     
00056     info_pos    = 0,
00057     type_pos    = info_pos + info_size,
00058     next_pos    = type_pos + type_size,
00059     
00060     info_mask   = (1 << info_size) - 1,
00061     type_mask   = (1 << type_size) - 1,
00062     next_mask   = (1 << next_size) - 1,
00063   };
00064 
00065   enum Type {                   // info field usage
00066     call,                       // unused
00067     absolute_jump,              // unused
00068     conditional_jump,           // condition code
00069     ic_info,                    // flags
00070   };
00071 
00072   void init(Label& L, Type type, int info) {
00073     assert(!L.is_bound(), "label is bound");
00074     int next = 0;
00075     if (L.is_unbound()) {
00076       next = L.pos();
00077       assert(next > 0, "Displacements must be at positions > 0");
00078     }
00079     assert((next & ~next_mask) == 0, "next field too small");
00080     assert((type & ~type_mask) == 0, "type field too small");
00081     assert((info & ~info_mask) == 0, "info field too small");
00082     _data = (next << next_pos) | (type << type_pos) | (info << info_pos);
00083   }
00084 
00085   int  data() const             { return _data; }
00086   int  info() const             { return     ((_data >> info_pos) & info_mask); }
00087   Type type() const             { return Type((_data >> type_pos) & type_mask); }
00088   void next(Label & L) const    { int n    = ((_data >> next_pos) & next_mask); n > 0 ? L.link_to(n) : L.unuse(); }
00089   void link_to(Label& L)        { init(L, type(), info()); }
00090     
00091   Displacement(int data)        { _data = data; }
00092 
00093   Displacement(Label& L, Type type, int info) {
00094     init(L, type, info);
00095   }
00096 
00097   void print() {
00098     char* s;
00099     switch (type()) {
00100       case call            : s = "call"; break;
00101       case absolute_jump   : s = "jmp "; break;
00102       case conditional_jump: s = "jcc "; break;
00103       case ic_info         : s = "nlr "; break;
00104       default              : s = "????"; break;
00105     }
00106     std->print("%s (info = 0x%x)", s, info());
00107   }
00108 
00109   friend class Assembler;
00110   friend class MacroAssembler;
00111 };
00112 
00113 
00114 // Use macros (otherwise must also declare Displacement class in .hpp file)
00115 #define disp_at(L)              Displacement(long_at((L).pos()))
00116 #define disp_at_put(L,disp)     long_at_put((L).pos(), (disp).data())
00117 #define emit_disp(L,type,info)  { Displacement disp((L), (type), (info));       \
00118                                   L.link_to(offset());                          \
00119                                   emit_long(int(disp.data()));                  \
00120                                 }
00121 
00122 // Implementation of Register
00123 char* registerNames[nofRegisters] = {"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"};
00124 
00125 char* Register::name() const {
00126   return isValid() ? registerNames[_number] : "noreg";
00127 }
00128 
00129 
00130 // Implementation of Address
00131 
00132 Address::Address() {
00133   _base  = noreg;
00134   _index = noreg;
00135   _scale = no_scale;
00136   _disp  = 0;
00137   _rtype = relocInfo::none;
00138 }
00139 
00140 
00141 Address::Address(int disp, relocInfo::relocType rtype) {
00142   _base  = noreg;
00143   _index = noreg;
00144   _scale = no_scale;
00145   _disp  = disp;
00146   _rtype = rtype;
00147 }
00148 
00149 
00150 Address::Address(Register base, int disp, relocInfo::relocType rtype) {
00151   _base  = base;
00152   _index = noreg;
00153   _scale = no_scale;
00154   _disp  = disp;
00155   _rtype = rtype;
00156 }
00157 
00158 
00159 Address::Address(Register base, Register index, ScaleFactor scale, int disp, relocInfo::relocType rtype) {
00160   assert((index == noreg) == (scale == Address::no_scale), "inconsistent address");
00161   _base  = base;
00162   _index = index;
00163   _scale = scale;
00164   _disp  = disp;
00165   _rtype = rtype;
00166 }
00167 
00168 
00169 // Implementation of Assembler
00170 
00171 Assembler::Assembler(CodeBuffer* code) {
00172   _code        = code;
00173   _code_begin  = code->code_begin();
00174   _code_limit  = code->code_limit();
00175   _code_pos    = code->code_end();
00176 }
00177 
00178 
00179 void Assembler::finalize() {
00180   if (_unbound_label.is_unbound()) {
00181     bind_to(_unbound_label, _binding_pos);
00182   }
00183 }
00184 
00185 
00186 inline void Assembler::emit_byte(int x) {
00187   assert(isByte(x), "not a byte");
00188   *(unsigned char*)_code_pos = (unsigned char)x;
00189   _code_pos += sizeof(unsigned char);
00190   code()->set_code_end(_code_pos);
00191 }
00192 
00193 
00194 inline void Assembler::emit_long(int x) {
00195   *(int*)_code_pos = x;
00196   _code_pos += sizeof(int);
00197   code()->set_code_end(_code_pos);
00198 }
00199 
00200 
00201 inline void Assembler::emit_data(int data, relocInfo::relocType rtype) {
00202   if (rtype != relocInfo::none) code()->relocate(_code_pos, rtype);
00203   emit_long(data);
00204 }
00205 
00206 
00207 void Assembler::emit_arith_b(int op1, int op2, Register dst, int imm8) {
00208   guarantee(dst.hasByteRegister(), "must have byte register");
00209   assert(isByte(op1) && isByte(op2), "wrong opcode");
00210   assert(isByte(imm8), "not a byte");
00211   assert((op1 & 0x01) == 0, "should be 8bit operation");
00212   emit_byte(op1);
00213   emit_byte(op2 | dst.number());
00214   emit_byte(imm8);
00215 }
00216 
00217 
00218 void Assembler::emit_arith(int op1, int op2, Register dst, int imm32) {
00219   assert(isByte(op1) && isByte(op2), "wrong opcode");
00220   assert((op1 & 0x01) == 1, "should be 32bit operation");
00221   assert((op1 & 0x02) == 0, "sign-extension bit should not be set");
00222   if (is8bit(imm32)) {
00223     emit_byte(op1 | 0x02); // set sign bit
00224     emit_byte(op2 | dst.number());
00225     emit_byte(imm32 & 0xFF);
00226   } else {
00227     emit_byte(op1);
00228     emit_byte(op2 | dst.number());
00229     emit_long(imm32);
00230   }
00231 }
00232 
00233 
00234 void Assembler::emit_arith(int op1, int op2, Register dst, oop obj) {
00235   assert(isByte(op1) && isByte(op2), "wrong opcode");
00236   assert((op1 & 0x01) == 1, "should be 32bit operation");
00237   assert((op1 & 0x02) == 0, "sign-extension bit should not be set");
00238   emit_byte(op1);
00239   emit_byte(op2 | dst.number());
00240   emit_data((int)obj, relocInfo::oop_type);
00241 }
00242 
00243 
00244 void Assembler::emit_arith(int op1, int op2, Register dst, Register src) {
00245   assert(isByte(op1) && isByte(op2), "wrong opcode");
00246   emit_byte(op1);
00247   emit_byte(op2 | dst.number() << 3 | src.number());
00248 }
00249 
00250 
00251 void Assembler::emit_operand(Register reg, Register base, Register index, Address::ScaleFactor scale, int disp, relocInfo::relocType rtype) {
00252   if (base.isValid()) {
00253     if (index.isValid()) {
00254       assert(scale != Address::no_scale, "inconsistent address");
00255       // [base + index*scale + disp]
00256       if (disp == 0 && rtype == relocInfo::none) {
00257         // [base + index*scale]
00258         // [00 reg 100][ss index base]
00259         assert(index != esp && base != ebp, "illegal addressing mode");
00260         emit_byte(0x04 | reg.number() << 3);
00261         emit_byte(scale << 6 | index.number() << 3 | base.number());
00262       } else if (is8bit(disp) && rtype == relocInfo::none) {
00263         // [base + index*scale + imm8]
00264         // [01 reg 100][ss index base] imm8
00265         assert(index != esp, "illegal addressing mode");
00266         emit_byte(0x44 | reg.number() << 3);
00267         emit_byte(scale << 6 | index.number() << 3 | base.number());
00268         emit_byte(disp & 0xFF);
00269       } else {
00270         // [base + index*scale + imm32]
00271         // [10 reg 100][ss index base] imm32
00272         assert(index != esp, "illegal addressing mode");
00273         emit_byte(0x84 | reg.number() << 3);
00274         emit_byte(scale << 6 | index.number() << 3 | base.number());
00275         emit_data(disp, rtype);
00276       }
00277     } else if (base == esp) {
00278       // [esp + disp]
00279       if (disp == 0 && rtype == relocInfo::none) {
00280         // [esp]
00281         // [00 reg 100][00 100 100]
00282         emit_byte(0x04 | reg.number() << 3);
00283         emit_byte(0x24);
00284       } else if (is8bit(disp) && rtype == relocInfo::none) {
00285         // [esp + imm8]
00286         // [01 reg 100][00 100 100] imm8
00287         emit_byte(0x44 | reg.number() << 3);
00288         emit_byte(0x24);
00289         emit_byte(disp & 0xFF);
00290       } else {
00291         // [esp + imm32]
00292         // [10 reg 100][00 100 100] imm32
00293         emit_byte(0x84 | reg.number() << 3);
00294         emit_byte(0x24);
00295         emit_data(disp, rtype);
00296       }
00297     } else {
00298       // [base + disp]
00299       assert(base != esp, "illegal addressing mode");
00300       if (disp == 0 && rtype == relocInfo::none && base != ebp) {
00301         // [base]
00302         // [00 reg base]
00303         assert(base != ebp, "illegal addressing mode");
00304         emit_byte(0x00 | reg.number() << 3 | base.number());
00305       } else if (is8bit(disp) && rtype == relocInfo::none) {
00306         // [base + imm8]
00307         // [01 reg base] imm8
00308         emit_byte(0x40 | reg.number() << 3 | base.number());
00309         emit_byte(disp & 0xFF);
00310       } else {
00311         // [base + imm32]
00312         // [10 reg base] imm32
00313         emit_byte(0x80 | reg.number() << 3 | base.number());
00314         emit_data(disp, rtype);
00315       }
00316     }
00317   } else {
00318     if (index.isValid()) {
00319       assert(scale != Address::no_scale, "inconsistent address");
00320       // [index*scale + disp]
00321       // [00 reg 100][ss index 101] imm32
00322       assert(index != esp, "illegal addressing mode");
00323       emit_byte(0x04 | reg.number() << 3);
00324       emit_byte(scale << 6 | index.number() << 3 | 0x05);
00325       emit_data(disp, rtype);
00326     } else {
00327       // [disp]
00328       // [00 reg 101] imm32
00329       emit_byte(0x05 | reg.number() << 3);
00330       emit_data(disp, rtype);
00331     }
00332   }
00333 }
00334 
00335 
00336 void Assembler::emit_operand(Register reg, Address adr) {
00337   emit_operand(reg, adr._base, adr._index, adr._scale, adr._disp, adr._rtype);
00338 }
00339 
00340 
00341 void Assembler::emit_farith(int b1, int b2, int i) {
00342   assert(isByte(b1) && isByte(b2), "wrong opcode");
00343   assert(0 <= i &&  i < 8, "illegal stack offset");
00344   emit_byte(b1);
00345   emit_byte(b2 + i);
00346 }
00347 
00348 
00349 void Assembler::pushad() {
00350   emit_byte(0x60);
00351 }
00352 
00353 
00354 void Assembler::popad() {
00355   emit_byte(0x61);
00356 }
00357 
00358 
00359 void Assembler::pushl(int imm32) {
00360   emit_byte(0x68);
00361   emit_long(imm32);
00362 }
00363 
00364   
00365 void Assembler::pushl(oop obj) {
00366   emit_byte(0x68);
00367   emit_data((int)obj, relocInfo::oop_type);
00368 }
00369 
00370   
00371 void Assembler::pushl(Register src) {
00372   emit_byte(0x50 | src.number());
00373 }
00374 
00375 
00376 void Assembler::pushl(Address src) {
00377   emit_byte(0xFF);
00378   emit_operand(esi, src);
00379 }
00380 
00381 
00382 void Assembler::popl(Register dst) {
00383   emit_byte(0x58 | dst.number());
00384 }
00385 
00386 
00387 void Assembler::popl(Address dst) {
00388   emit_byte(0x8F);
00389   emit_operand(eax, dst);
00390 }
00391 
00392 
00393 void Assembler::movb(Register dst, Address src) {
00394   guarantee(dst.hasByteRegister(), "must have byte register"); 
00395   emit_byte(0x8A);
00396   emit_operand(dst, src);
00397 }
00398 
00399 
00400 void Assembler::movb(Address dst, int imm8) {
00401   emit_byte(0xC6);
00402   emit_operand(eax, dst);
00403   emit_byte(imm8);
00404 }
00405 
00406 
00407 void Assembler::movb(Address dst, Register src) {
00408   guarantee(src.hasByteRegister(), "must have byte register"); 
00409   emit_byte(0x88);
00410   emit_operand(src, dst);
00411 }
00412 
00413   
00414 void Assembler::movw(Register dst, Address src) {
00415   emit_byte(0x66);
00416   emit_byte(0x8B);
00417   emit_operand(dst, src);
00418 }
00419 
00420 
00421 void Assembler::movw(Address dst, Register src) {
00422   emit_byte(0x66);
00423   emit_byte(0x89);
00424   emit_operand(src, dst);
00425 }
00426 
00427 
00428 void Assembler::movl(Register dst, int imm32) {
00429   emit_byte(0xB8 | dst.number());
00430   emit_long(imm32);
00431 }
00432 
00433 
00434 void Assembler::movl(Register dst, oop obj) {
00435   emit_byte(0xB8 | dst.number());
00436   emit_data((int)obj, relocInfo::oop_type);
00437 }
00438 
00439 
00440 void Assembler::movl(Register dst, Register src) {
00441   emit_byte(0x8B);
00442   emit_byte(0xC0 | (dst.number() << 3) | src.number());
00443 }
00444 
00445 
00446 void Assembler::movl(Register dst, Address src) {
00447   emit_byte(0x8B);
00448   emit_operand(dst, src);
00449 }
00450 
00451 
00452 void Assembler::movl(Address dst, int imm32) {
00453   emit_byte(0xC7);
00454   emit_operand(eax, dst);
00455   emit_long(imm32);
00456 }
00457 
00458 
00459 void Assembler::movl(Address dst, oop obj) {
00460   emit_byte(0xC7);
00461   emit_operand(eax, dst);
00462   emit_data((int)obj, relocInfo::oop_type);
00463 }
00464 
00465 
00466 void Assembler::movl(Address dst, Register src) {
00467   emit_byte(0x89);
00468   emit_operand(src, dst);
00469 }
00470 
00471 
00472 void Assembler::movsxb(Register dst, Address src) {
00473   emit_byte(0x0F);
00474   emit_byte(0xBE);
00475   emit_operand(dst, src);
00476 }
00477 
00478 
00479 void Assembler::movsxb(Register dst, Register src) {
00480   guarantee(src.hasByteRegister(), "must have byte register"); 
00481   emit_byte(0x0F);
00482   emit_byte(0xBE);
00483   emit_byte(0xC0 | (dst.number() << 3) | src.number());
00484 }
00485 
00486 
00487 void Assembler::movsxw(Register dst, Address src) {
00488   emit_byte(0x0F);
00489   emit_byte(0xBF);
00490   emit_operand(dst, src);
00491 }
00492 
00493   
00494 void Assembler::movsxw(Register dst, Register src) {
00495   emit_byte(0x0F);
00496   emit_byte(0xBF);
00497   emit_byte(0xC0 | (dst.number() << 3) | src.number());
00498 }
00499 
00500 
00501 void Assembler::cmovccl(Condition cc, Register dst, int imm32) {
00502   Unimplemented();
00503 }
00504 
00505 
00506 void Assembler::cmovccl(Condition cc, Register dst, oop obj) {
00507   Unimplemented();
00508 }
00509 
00510 
00511 void Assembler::cmovccl(Condition cc, Register dst, Register src) {
00512   Unimplemented();
00513 }
00514 
00515 
00516 void Assembler::cmovccl(Condition cc, Register dst, Address src) {
00517   Unimplemented();
00518 }
00519 
00520   
00521 void Assembler::adcl(Register dst, int imm32) {
00522   emit_arith(0x81, 0xD0, dst, imm32);
00523 }
00524 
00525 
00526 void Assembler::adcl(Register dst, Register src) {
00527   emit_arith(0x13, 0xC0, dst, src);
00528 }
00529 
00530 
00531 void Assembler::addl(Address dst, int imm32) {
00532   emit_byte(0x81);
00533   emit_operand(eax, dst);
00534   emit_long(imm32);
00535 }
00536 
00537 
00538 void Assembler::addl(Register dst, int imm32) {
00539   emit_arith(0x81, 0xC0, dst, imm32);
00540 }
00541 
00542 
00543 void Assembler::addl(Register dst, Register src) {
00544   emit_arith(0x03, 0xC0, dst, src);
00545 }
00546 
00547 
00548 void Assembler::andl(Register dst, int imm32) {
00549   emit_arith(0x81, 0xE0, dst, imm32);
00550 }
00551 
00552 
00553 void Assembler::andl(Register dst, Register src) {
00554   emit_arith(0x23, 0xC0, dst, src);
00555 }
00556 
00557 
00558 void Assembler::cmpl(Address dst, int imm32) {
00559   emit_byte(0x81);
00560   emit_operand(edi, dst);
00561   emit_long(imm32);
00562 }
00563 
00564 
00565 void Assembler::cmpl(Address dst, oop obj) {
00566   emit_byte(0x81);
00567   emit_operand(edi, dst);
00568   emit_data((int)obj, relocInfo::oop_type);
00569 }
00570 
00571 
00572 void Assembler::cmpl(Register dst, int imm32) {
00573   emit_arith(0x81, 0xF8, dst, imm32);
00574 }
00575 
00576 
00577 void Assembler::cmpl(Register dst, oop obj) {
00578   emit_arith(0x81, 0xF8, dst, obj);
00579 }
00580 
00581 
00582 void Assembler::cmpl(Register dst, Register src) {
00583   emit_arith(0x3B, 0xC0, dst, src);
00584 }
00585 
00586 
00587 void Assembler::cmpl(Register dst, Address  src) {
00588   emit_byte(0x3B);
00589   emit_operand(dst, src);
00590 }
00591 
00592 
00593 void Assembler::decb(Register dst) {
00594   guarantee(dst.hasByteRegister(), "must have byte register"); 
00595   emit_byte(0xFE);
00596   emit_byte(0xC8 | dst.number());
00597 }
00598 
00599 
00600 void Assembler::decl(Register dst) {
00601   emit_byte(0x48 | dst.number());
00602 }
00603 
00604 
00605 void Assembler::idivl(Register src) {
00606   emit_byte(0xF7);
00607   emit_byte(0xF8 | src.number());
00608 }
00609 
00610 
00611 void Assembler::imull(Register dst, Register src) {
00612   emit_byte(0x0F);
00613   emit_byte(0xAF);
00614   emit_byte(0xC0 | dst.number() << 3 | src.number());
00615 }
00616 
00617 
00618 void Assembler::imull(Register dst, Register src, int value) {
00619   if (is8bit(value)) {
00620     emit_byte(0x6B);
00621     emit_byte(0xC0 | dst.number() << 3 | src.number());
00622     emit_byte(value);
00623   } else {
00624     emit_byte(0x69);
00625     emit_byte(0xC0 | dst.number() << 3 | src.number());
00626     emit_long(value);
00627   }
00628 }
00629 
00630 
00631 void Assembler::incl(Register dst) {
00632   emit_byte(0x40 | dst.number());
00633 }
00634 
00635 
00636 void Assembler::incl(Address dst) {
00637   emit_byte(0xFF);
00638   emit_operand(eax, dst);
00639 }
00640 
00641 
00642 void Assembler::leal(Register dst, Address src) {
00643   emit_byte(0x8D);
00644   emit_operand(dst, src);
00645 }
00646 
00647 
00648 void Assembler::mull(Register src) {
00649   emit_byte(0xF7);
00650   emit_byte(0xE0 | src.number());
00651 }
00652 
00653 
00654 void Assembler::negl(Register dst) {
00655   emit_byte(0xF7);
00656   emit_byte(0xD8 | dst.number());
00657 }
00658 
00659 
00660 void Assembler::notl(Register dst) {
00661   emit_byte(0xF7);
00662   emit_byte(0xD0 | dst.number());
00663 }
00664 
00665 
00666 void Assembler::orl(Register dst, int imm32) {
00667   emit_arith(0x81, 0xC8, dst, imm32);
00668 }
00669 
00670 
00671 void Assembler::orl(Register dst, Register src) {
00672   emit_arith(0x0B, 0xC0, dst, src);
00673 }
00674 
00675 
00676 
00677 void Assembler::orl(Register dst, Address src) {
00678   emit_byte(0x0B);
00679   emit_operand(dst, src);
00680 }
00681 
00682 
00683 void Assembler::rcll(Register dst, int imm8) {
00684   assert(isShiftCount(imm8), "illegal shift count");
00685   if (imm8 == 1) {
00686     emit_byte(0xD1);
00687     emit_byte(0xD0 | dst.number());
00688   } else {
00689     emit_byte(0xC1);
00690     emit_byte(0xD0 | dst.number());
00691     emit_byte(imm8);
00692   }
00693 }
00694 
00695 
00696 void Assembler::sarl(Register dst, int imm8) {
00697   assert(isShiftCount(imm8), "illegal shift count");
00698   if (imm8 == 1) {
00699     emit_byte(0xD1);
00700     emit_byte(0xF8 | dst.number());
00701   } else {
00702     emit_byte(0xC1);
00703     emit_byte(0xF8 | dst.number());
00704     emit_byte(imm8);
00705   }
00706 }
00707 
00708 
00709 void Assembler::sarl(Register dst) {
00710   emit_byte(0xD3);
00711   emit_byte(0xF8 | dst.number());
00712 }
00713 
00714 
00715 void Assembler::sbbl(Register dst, int imm32) {
00716   Unimplemented();
00717 }
00718 
00719 
00720 void Assembler::sbbl(Register dst, Register src) {
00721   emit_arith(0x1B, 0xC0, dst, src);
00722 }
00723 
00724 
00725 void Assembler::shldl(Register dst, Register src) {
00726   emit_byte(0x0F);
00727   emit_byte(0xA5);
00728   emit_byte(0xC0 | src.number() << 3 | dst.number());
00729 }
00730 
00731 
00732 void Assembler::shll(Register dst, int imm8) {
00733   assert(isShiftCount(imm8), "illegal shift count");
00734   if (imm8 == 1 ) {
00735     emit_byte(0xD1);
00736     emit_byte(0xE0 | dst.number());
00737   } else {
00738     emit_byte(0xC1);
00739     emit_byte(0xE0 | dst.number());
00740     emit_byte(imm8);
00741   }
00742 }
00743 
00744 
00745 void Assembler::shll(Register dst) {
00746   emit_byte(0xD3);
00747   emit_byte(0xE0 | dst.number());
00748 }
00749 
00750 
00751 void Assembler::shrdl(Register dst, Register src) {
00752   emit_byte(0x0F);
00753   emit_byte(0xAD);
00754   emit_byte(0xC0 | src.number() << 3 | dst.number());
00755 }
00756 
00757 
00758 void Assembler::shrl(Register dst, int imm8) {
00759   assert(isShiftCount(imm8), "illegal shift count");
00760   emit_byte(0xC1);
00761   emit_byte(0xE8 | dst.number());
00762   emit_byte(imm8);
00763 }
00764 
00765 
00766 void Assembler::shrl(Register dst) {
00767   emit_byte(0xD3);
00768   emit_byte(0xE8 | dst.number());
00769 }
00770 
00771   
00772 void Assembler::subl(Register dst, int imm32) {
00773   emit_arith(0x81, 0xE8, dst, imm32);
00774 }
00775 
00776 
00777 void Assembler::subl(Register dst, Register src) {
00778   emit_arith(0x2B, 0xC0, dst, src);
00779 }
00780 
00781 
00782 void Assembler::testb(Register dst, int imm8) {
00783   guarantee(dst.hasByteRegister(), "must have byte register"); 
00784   emit_arith_b(0xF6, 0xC0, dst, imm8);
00785 }
00786 
00787 
00788 void Assembler::testl(Register dst, int imm32) {
00789   // not using emit_arith because test
00790   // doesn't support sign-extension of
00791   // 8bit operands
00792   if (dst.number() == 0) {
00793     emit_byte(0xA9);
00794   } else {
00795     emit_byte(0xF7);
00796     emit_byte(0xC0 | dst.number());
00797   }
00798   emit_long(imm32);
00799 }
00800 
00801 
00802 void Assembler::testl(Register dst, Register src) {
00803   emit_arith(0x85, 0xC0, dst, src);
00804 }
00805 
00806 
00807 void Assembler::xorl(Register dst, int imm32) {
00808   emit_arith(0x81, 0xF0, dst, imm32);
00809 }
00810 
00811 
00812 void Assembler::xorl(Register dst, Register src) {
00813   emit_arith(0x33, 0xC0, dst, src);
00814 }
00815 
00816 
00817 void Assembler::hlt() {
00818   emit_byte(0xF4);
00819 }
00820 
00821 
00822 void Assembler::int3() {
00823   if (EnableInt3) emit_byte(0xCC);
00824 }
00825 
00826 
00827 void Assembler::nop() {
00828   emit_byte(0x90);
00829 }
00830 
00831 
00832 void Assembler::ret(int imm16) {
00833   if (imm16 == 0) {
00834     emit_byte(0xC3);
00835   } else {
00836     emit_byte(0xC2);
00837     emit_byte(imm16 & 0xFF);
00838     emit_byte((imm16 >> 8) & 0xFF);
00839   }
00840 }
00841 
00842 
00843 // Labels refer to positions in the (to be) generated code.
00844 // There are bound, unbound and undefined labels.
00845 //
00846 // Bound labels refer to known positions in the already
00847 // generated code. pos() is the position the label refers to.
00848 //
00849 // Unbound labels refer to unknown positions in the code
00850 // to be generated; pos() is the position of the 32bit
00851 // Displacement of the last instruction using the label.
00852 //
00853 // Undefined labels are labels that haven't been used yet.
00854 // They refer to no position at all.
00855 
00856 
00857 void Assembler::print(Label& L) {
00858   if (L.is_unused()) {
00859     std->print_cr("undefined label");
00860   } else if (L.is_bound()) {
00861     std->print_cr("bound label to %d", L.pos());
00862   } else if (L.is_unbound()) {
00863     Label l = L;
00864     std->print_cr("unbound label");
00865     while (l.is_unbound()) {
00866       Displacement disp = disp_at(l);
00867       std->print("@ %d ", l.pos());
00868       disp.print();
00869       std->cr();
00870       disp.next(l);
00871     }
00872   } else {
00873     std->print_cr("label in inconsistent state (pos = %d)", L._pos);
00874   }
00875 }
00876 
00877 
00878 void Assembler::bind_to(Label& L, int pos) {
00879   bool tellRobert = false;
00880 
00881   assert(0 <= pos && pos <= offset(), "must have a valid binding position");
00882   while (L.is_unbound()) {
00883     Displacement disp = disp_at(L);
00884     int fixup_pos = L.pos();
00885     int imm32 = 0;
00886     switch (disp.type()) {
00887       case Displacement::call:
00888         { assert(byte_at(fixup_pos - 1) == 0xE8, "call expected");
00889           imm32 = pos - (fixup_pos + sizeof(int));
00890         }
00891         break;
00892       case Displacement::absolute_jump:
00893         { assert(byte_at(fixup_pos - 1) == 0xE9, "jmp expected");
00894           imm32 = pos - (fixup_pos + sizeof(int));
00895           if (imm32 == 0 && EliminateJumpsToJumps) tellRobert = true;
00896         }
00897         break;
00898       case Displacement::conditional_jump:
00899         { assert(byte_at(fixup_pos - 2) == 0x0F, "jcc expected");
00900           assert(byte_at(fixup_pos - 1) == (0x80 | disp.info()), "jcc expected");
00901           imm32 = pos - (fixup_pos + sizeof(int));
00902         }
00903         break;
00904       case Displacement::ic_info:
00905         { assert(byte_at(fixup_pos - 1) == 0xA9, "test eax expected");
00906           int offs = pos - (fixup_pos - IC_Info::info_offset);
00907           assert(((offs << IC_Info::number_of_flags) >> IC_Info::number_of_flags) == offs, "NLR offset out of bounds");
00908           imm32 = (offs << IC_Info::number_of_flags) | disp.info();
00909         }
00910         break;
00911       default:
00912         ShouldNotReachHere();
00913     }
00914     long_at_put(fixup_pos, imm32);
00915     disp.next(L);
00916   }
00917   L.bind_to(pos);
00918 
00919   if (tellRobert) {
00920     //warning("jmp to next has not been eliminated - tell Robert, please");
00921     code()->decode();
00922   }
00923 }
00924 
00925 
00926 void Assembler::link_to(Label& L, Label& appendix) {
00927   if (appendix.is_unbound()) {
00928     if (L.is_unbound()) {
00929       // append appendix to L's list
00930       Label p, q = L;
00931       do { p = q; disp_at(q).next(q); } while (q.is_unbound());
00932       Displacement disp = disp_at(p);
00933       disp.link_to(appendix);
00934       disp_at_put(p, disp);
00935       p.unuse(); // to avoid assertion failure in ~Label
00936     } else {
00937       // L is empty, simply use appendix
00938       L = appendix;
00939     }
00940   }
00941   appendix.unuse(); // appendix should not be used anymore
00942 }
00943 
00944 
00945 void Assembler::bind(Label& L) {
00946   assert(!L.is_bound(), "label can only be bound once");
00947   if (EliminateJumpsToJumps) {
00948     // resolve unbound label
00949     if (_unbound_label.is_unbound()) {
00950       // unbound label exists => link it with L if same binding position, otherwise fix it
00951       if (_binding_pos == offset()) {
00952         // link it to L's list
00953         link_to(L, _unbound_label);
00954       } else {
00955         // otherwise bind unbound label
00956         assert(_binding_pos < offset(), "assembler error");
00957         bind_to(_unbound_label, _binding_pos);
00958       }
00959     }
00960     assert(!_unbound_label.is_unbound(), "assembler error");
00961     // try to eliminate jumps to next instruction
00962     while (L.is_unbound() && (L.pos() + int(sizeof(int)) == offset()) && (disp_at(L).type() == Displacement::absolute_jump)) {
00963       // previous instruction is jump jumping immediately after it => eliminate it
00964       const int long_size = 5;
00965       assert(byte_at(offset() - long_size) == 0xE9, "jmp expected");
00966       if (PrintJumpElimination) std->print_cr("@ %d jump to next eliminated", L.pos());
00967       // remove first entry from label list
00968       disp_at(L).next(L);
00969       // eliminate instruction (set code pointers back)
00970       _code_pos -= long_size;
00971       code()->set_code_end(_code_pos);
00972     }
00973     // delay fixup of L => store it as unbound label
00974     _unbound_label = L;
00975     _binding_pos = offset();
00976     L.unuse();
00977   }
00978   bind_to(L, offset());
00979 }
00980 
00981 
00982 void Assembler::merge(Label& L, Label& with) {
00983   Unimplemented();
00984 }
00985 
00986 
00987 void Assembler::call(Label& L) {
00988   if (L.is_bound()) {
00989     const int long_size = 5;
00990     int offs = L.pos() - offset();
00991     assert(offs <= 0, "assembler error");
00992     // 1110 1000 #32-bit disp
00993     emit_byte(0xE8);
00994     emit_long(offs - long_size);
00995   } else {
00996     // 1110 1000 #32-bit disp
00997     emit_byte(0xE8);
00998     emit_disp(L, Displacement::call, 0);
00999   }
01000 }
01001 
01002 
01003 void Assembler::call(char* entry, relocInfo::relocType rtype) {
01004   emit_byte(0xE8);
01005   emit_data((int)entry - ((int)_code_pos + sizeof(long)), rtype);
01006 }
01007 
01008 
01009 void Assembler::call(Register dst) {
01010   emit_byte(0xFF);
01011   emit_byte(0xD0 | dst.number());
01012 }
01013 
01014 
01015 void Assembler::call(Address adr) {
01016   emit_byte(0xFF);
01017   emit_operand(edx, adr);
01018 }
01019 
01020 
01021 void Assembler::jmp(char* entry, relocInfo::relocType rtype) {
01022   emit_byte(0xE9);
01023   emit_data((int)entry - ((int)_code_pos + sizeof(long)), rtype);
01024 }
01025 
01026 
01027 void Assembler::jmp(Register reg) {
01028   emit_byte(0xFF);
01029   emit_byte(0xE0 | reg.number());
01030 }
01031 
01032 
01033 void Assembler::jmp(Address adr) {
01034   emit_byte(0xFF);
01035   emit_operand(esp, adr);
01036 }
01037 
01038 
01039 void Assembler::jmp(Label& L) {
01040   if (L.is_bound()) {
01041     const int short_size = 2;
01042     const int long_size  = 5;
01043     int offs = L.pos() - offset();
01044     assert(offs <= 0, "assembler error");
01045     if (isByte(offs - short_size)) {
01046       // 1110 1011 #8-bit disp
01047       emit_byte(0xEB);
01048       emit_byte((offs - short_size) & 0xFF);
01049     } else {
01050       // 1110 1001 #32-bit disp
01051       emit_byte(0xE9);
01052       emit_long(offs - long_size);
01053     }
01054   } else {
01055     if (EliminateJumpsToJumps && _unbound_label.is_unbound() && _binding_pos == offset()) {
01056       // current position is target of jumps
01057       if (PrintJumpElimination) {
01058         std->print_cr("eliminated jumps/calls to %d", _binding_pos);
01059         std->print("from ");
01060         print(_unbound_label);
01061       }
01062       link_to(L, _unbound_label);
01063     }
01064     // 1110 1001 #32-bit disp
01065     emit_byte(0xE9);
01066     emit_disp(L, Displacement::absolute_jump, 0);
01067   }
01068 }
01069 
01070 
01071 void Assembler::jcc(Condition cc, Label& L) {
01072   assert((0 <= cc) && (cc < 16), "illegal cc");
01073   if (L.is_bound()) {
01074     const int short_size = 2;
01075     const int long_size  = 6;
01076     int offs = L.pos() - offset();
01077     assert(offs <= 0, "assembler error");
01078     if (isByte(offs - short_size)) {
01079       // 0111 tttn #8-bit disp
01080       emit_byte(0x70 | cc);
01081       emit_byte((offs - short_size) & 0xFF);
01082     } else {
01083       // 0000 1111 1000 tttn #32-bit disp
01084       emit_byte(0x0F);
01085       emit_byte(0x80 | cc);
01086       emit_long(offs - long_size);
01087     }
01088   } else {
01089     // 0000 1111 1000 tttn #32-bit disp
01090     // Note: could eliminate cond. jumps to this jump if condition
01091     //       is the same however, seems to be rather unlikely case.
01092     emit_byte(0x0F);
01093     emit_byte(0x80 | cc);
01094     emit_disp(L, Displacement::conditional_jump, cc);
01095   }
01096 }
01097 
01098 
01099 void Assembler::jcc(Condition cc, char* dst, relocInfo::relocType rtype) {
01100   assert((0 <= cc) && (cc < 16), "illegal cc");
01101   // 0000 1111 1000 tttn #32-bit disp
01102   emit_byte(0x0F);
01103   emit_byte(0x80 | cc);
01104   emit_data((int)dst - ((int)_code_pos + sizeof(long)), rtype);
01105 }
01106 
01107 
01108 void Assembler::ic_info(Label& L, int flags) {
01109   assert((unsigned int)flags >> IC_Info::number_of_flags == 0, "too many flags set");
01110   if (L.is_bound()) {
01111     int offs = L.pos() - offset();
01112     assert(offs <= 0, "assembler error");
01113     assert(((offs << IC_Info::number_of_flags) >> IC_Info::number_of_flags) == offs, "NLR offset out of bounds");
01114     emit_byte(0xA9);
01115     emit_long((offs << IC_Info::number_of_flags) | flags);
01116   } else {
01117     emit_byte(0xA9);
01118     emit_disp(L, Displacement::ic_info, flags);
01119   }
01120 }
01121 
01122 
01123 // FPU instructions
01124 
01125 void Assembler::fld1() {
01126   emit_byte(0xD9);
01127   emit_byte(0xE8);
01128 }
01129 
01130 
01131 void Assembler::fldz() {
01132   emit_byte(0xD9);
01133   emit_byte(0xEE);
01134 }
01135 
01136 
01137 void Assembler::fld_s(Address adr) {
01138   emit_byte(0xD9);
01139   emit_operand(eax, adr);
01140 }
01141 
01142 
01143 void Assembler::fld_d(Address adr) {
01144   emit_byte(0xDD);
01145   emit_operand(eax, adr);
01146 }
01147 
01148 
01149 void Assembler::fstp_s(Address adr) {
01150   emit_byte(0xD9);
01151   emit_operand(ebx, adr);
01152 }
01153 
01154 
01155 void Assembler::fstp_d(Address adr) {
01156   emit_byte(0xDD);
01157   emit_operand(ebx, adr);
01158 }
01159 
01160 
01161 void Assembler::fild_s(Address adr) {
01162   emit_byte(0xDB);
01163   emit_operand(eax, adr);
01164 }
01165 
01166 
01167 void Assembler::fild_d(Address adr) {
01168   emit_byte(0xDF);
01169   emit_operand(ebp, adr);
01170 }
01171 
01172 
01173 void Assembler::fistp_s(Address adr) {
01174   emit_byte(0xDB);
01175   emit_operand(ebx, adr);
01176 }
01177 
01178 
01179 void Assembler::fistp_d(Address adr) {
01180   emit_byte(0xDF);
01181   emit_operand(edi, adr);
01182 }
01183 
01184 
01185 void Assembler::fabs() {
01186   emit_byte(0xD9);
01187   emit_byte(0xE1);
01188 }
01189 
01190 
01191 void Assembler::fchs() {
01192   emit_byte(0xD9);
01193   emit_byte(0xE0);
01194 }
01195 
01196 
01197 void Assembler::fadd(int i) {
01198   emit_farith(0xDC, 0xC0, i);
01199 }
01200 
01201 
01202 void Assembler::fsub(int i) {
01203   emit_farith(0xDC, 0xE8, i);
01204 }
01205 
01206 
01207 void Assembler::fmul(int i) {
01208   emit_farith(0xDC, 0xC8, i);
01209 }
01210 
01211 
01212 void Assembler::fdiv(int i) {
01213   emit_farith(0xDC, 0xF8, i);
01214 }
01215 
01216   
01217 void Assembler::faddp(int i) {
01218   emit_farith(0xDE, 0xC0, i);
01219 }
01220 
01221 
01222 void Assembler::fsubp(int i) {
01223   emit_farith(0xDE, 0xE8, i);
01224 }
01225 
01226 
01227 void Assembler::fsubrp(int i) {
01228   emit_farith(0xDE, 0xE0, i);
01229 }
01230 
01231 
01232 void Assembler::fmulp(int i) {
01233   emit_farith(0xDE, 0xC8, i);
01234 }
01235 
01236 
01237 void Assembler::fdivp(int i) {
01238   emit_farith(0xDE, 0xF8, i);
01239 }
01240 
01241 
01242 
01243 void Assembler::fprem() {
01244   emit_byte(0xD9);
01245   emit_byte(0xF8);
01246 }
01247 
01248 
01249 void Assembler::fprem1() {
01250   emit_byte(0xD9);
01251   emit_byte(0xF5);
01252 }
01253 
01254 
01255 void Assembler::fxch(int i) {
01256   emit_farith(0xD9, 0xC8, i);
01257 }
01258 
01259 
01260 void Assembler::fincstp() {
01261   emit_byte(0xD9);
01262   emit_byte(0xF7);
01263 }
01264 
01265 
01266 void Assembler::ffree(int i) {
01267   emit_farith(0xDD, 0xC0, i);
01268 }
01269 
01270 
01271 void Assembler::ftst() {
01272   emit_byte(0xD9);
01273   emit_byte(0xE4);
01274 }
01275 
01276 
01277 void Assembler::fcompp() {
01278   emit_byte(0xDE);
01279   emit_byte(0xD9);
01280 }
01281 
01282 
01283 void Assembler::fnstsw_ax() {
01284   emit_byte(0xdF);
01285   emit_byte(0xE0);
01286 }
01287 
01288 
01289 void Assembler::fwait() {
01290   emit_byte(0x9B);
01291 }
01292 
01293 
01294 // Implementation of MacroAssembler
01295 
01296 void MacroAssembler::align(int modulus) {
01297   while (offset() % modulus != 0) nop();
01298 }
01299 
01300 
01301 void MacroAssembler::test(Register dst, int imm8) {
01302   if (!CodeForP6 && dst.hasByteRegister()) {
01303     testb(dst, imm8);
01304   } else {
01305     testl(dst, imm8);
01306   }
01307 }
01308 
01309 
01310 void MacroAssembler::enter() {
01311   pushl(ebp);
01312   movl(ebp, esp);
01313 }
01314 
01315 
01316 void MacroAssembler::leave() {
01317   movl(esp, ebp);
01318   popl(ebp);
01319 }
01320 
01321 
01322 // Support for inlined data
01323 
01324 void MacroAssembler::inline_oop(oop o) {
01325   emit_byte(0xA9);
01326   emit_data((int)o, relocInfo::oop_type);
01327 }
01328 
01329 
01330 // Calls to C land
01331 //
01332 // When entering C land, the ebp & esp of the last Delta frame have to be recorded.
01333 // When leaving C land, last_Delta_fp has to be reset to 0. This is required to
01334 // allow proper stack traversal.
01335 
01336 void MacroAssembler::set_last_Delta_frame_before_call() {
01337   movl(Address((int)&last_Delta_fp, relocInfo::external_word_type), ebp);
01338   movl(Address((int)&last_Delta_sp, relocInfo::external_word_type), esp);
01339 }
01340 
01341 
01342 void MacroAssembler::set_last_Delta_frame_after_call() {
01343   addl(esp, oopSize);   // sets esp to value before call (i.e., before pushing the return address)
01344   set_last_Delta_frame_before_call();
01345   subl(esp, oopSize);   // resets esp to original value
01346 }
01347 
01348 
01349 void MacroAssembler::reset_last_Delta_frame() {
01350   movl(Address((int)&last_Delta_fp, relocInfo::external_word_type), 0);
01351 }
01352 
01353 
01354 void MacroAssembler::call_C(Label& L) {
01355   set_last_Delta_frame_before_call();
01356   call(L);
01357   reset_last_Delta_frame();
01358 }
01359 
01360 
01361 void MacroAssembler::call_C(Label& L, Label& nlrTestPoint) {
01362   set_last_Delta_frame_before_call();
01363   call(L);
01364   Assembler::ic_info(nlrTestPoint, 0);
01365   reset_last_Delta_frame();
01366 }
01367 
01368 
01369 void MacroAssembler::call_C(char* entry, relocInfo::relocType rtype) {
01370   set_last_Delta_frame_before_call();
01371   call(entry, rtype);
01372   reset_last_Delta_frame();
01373 }
01374 
01375 
01376 void MacroAssembler::call_C(char* entry, relocInfo::relocType rtype, Label& nlrTestPoint) {
01377   set_last_Delta_frame_before_call();
01378   call(entry, rtype);
01379   Assembler::ic_info(nlrTestPoint, 0);
01380   reset_last_Delta_frame();
01381 }
01382 
01383 
01384 void MacroAssembler::call_C(Register entry) {
01385   set_last_Delta_frame_before_call();
01386   call(entry);
01387   reset_last_Delta_frame();
01388 }
01389 
01390 
01391 void MacroAssembler::call_C(Register entry, Label& nlrTestPoint) {
01392   set_last_Delta_frame_before_call();
01393   call(entry);
01394   Assembler::ic_info(nlrTestPoint, 0);
01395   reset_last_Delta_frame();
01396 }
01397 
01398 
01399 // The following 3 macros implement C run-time calls with arguments. When setting up the
01400 // last Delta frame, the value pushed after last_Delta_sp MUST be a valid return address,
01401 // therefore an additional call to a little stub is required which does the parameter
01402 // passing.
01403 //
01404 // [return addr] \
01405 // [argument 1 ]  |   extra stub in C land
01406 //  ...           |
01407 // [argument n ] /
01408 // [return addr] <=== must be valid return address  \
01409 // [...        ] <--- last_Delta_sp                  |
01410 //  ...                                              | last Delta frame in Delta land
01411 // [...        ]                                     |
01412 // [previous fp] <--- last_Delta_fp                 /
01413 //
01414 // Note: The routines could be implemented slightly more efficient and shorter by
01415 // explicitly pushing/popping a valid return address instead of calling the extra
01416 // stub. However, currently the assembler doesn't support label pushes.
01417 
01418 
01419 void MacroAssembler::call_C(char* entry, Register arg1) {
01420   Label L1, L2;
01421   jmp(L1);
01422 
01423   bind(L2);
01424   pushl(arg1);
01425   call(entry, relocInfo::runtime_call_type);
01426   addl(esp, 1*oopSize);
01427   ret(0);
01428 
01429   bind(L1);
01430   call_C(L2);
01431 }
01432 
01433 
01434 void MacroAssembler::call_C(char* entry, Register arg1, Register arg2) {
01435   Label L1, L2;
01436   jmp(L1);
01437 
01438   bind(L2);
01439   pushl(arg2);
01440   pushl(arg1);
01441   call(entry, relocInfo::runtime_call_type);
01442   addl(esp, 2*oopSize);
01443   ret(0);
01444 
01445   bind(L1);
01446   call_C(L2);
01447 }
01448 
01449 
01450 void MacroAssembler::call_C(char* entry, Register arg1, Register arg2, Register arg3) {
01451   Label L1, L2;
01452   jmp(L1);
01453 
01454   bind(L2);
01455   pushl(arg3);
01456   pushl(arg2);
01457   pushl(arg1);
01458   call(entry, relocInfo::runtime_call_type);
01459   addl(esp, 3*oopSize);
01460   ret(0);
01461 
01462   bind(L1);
01463   call_C(L2);
01464 }
01465 
01466 
01467 void MacroAssembler::call_C(char* entry, Register arg1, Register arg2, Register arg3, Register arg4) {
01468   Label L1, L2;
01469   jmp(L1);
01470 
01471   bind(L2);
01472   pushl(arg4);
01473   pushl(arg3);
01474   pushl(arg2);
01475   pushl(arg1);
01476   call(entry, relocInfo::runtime_call_type);
01477   addl(esp, 4*oopSize);
01478   ret(0);
01479 
01480   bind(L1);
01481   call_C(L2);
01482 }
01483 
01484 
01485 void MacroAssembler::store_check(Register obj, Register tmp) {
01486   // Does a store check for the oop in register obj. The content of
01487   // register obj is destroyed afterwards.
01488   // Note: Could be optimized by hardwiring the byte map base address
01489   // in the code - however relocation would be necessary whenever the
01490   // base changes. Advantage: only one instead of two instructions.
01491   assert(obj != tmp, "registers must be different");
01492   movl(tmp, Address((int)&byte_map_base, relocInfo::external_word_type));
01493   shrl(obj, card_shift);
01494   movb(Address(tmp, obj, Address::times_1), 0);
01495 }
01496 
01497 
01498 void MacroAssembler::fpu_mask_and_cond_for(Condition cc, int& mask, Condition& cond) {
01499   switch (cc) {
01500     case equal          : mask = 0x4000; cond = notZero;        break;
01501     case notEqual       : mask = 0x4000; cond = zero;           break;
01502     case less           : mask = 0x0100; cond = notZero;        break;
01503     case lessEqual      : mask = 0x4500; cond = notZero;        break;
01504     case greater        : mask = 0x4500; cond = zero;           break;
01505     case greaterEqual   : mask = 0x0100; cond = zero;           break;
01506     default             : Unimplemented();
01507   };
01508 }
01509 
01510 
01511 void MacroAssembler::fpop() {
01512   ffree();
01513   fincstp();
01514 }
01515 
01516 
01517 // debugging
01518 
01519 void MacroAssembler::print_reg(char* name, oop obj) {
01520   std->print("%s = ", name);
01521   if (obj == NULL) {
01522     std->print_cr("NULL");
01523   } else if (obj->is_smi()) {
01524     std->print_cr("smi (%d)", smiOop(obj)->value());
01525   } else if (obj->is_mem() && Universe::is_heap((oop*)obj)) {
01526     // use explicit checks to avoid crashes even in a broken system
01527     if (obj == Universe::nilObj()) {
01528       std->print_cr("nil (0x%08x)", obj);
01529     } else if (obj == Universe::trueObj()) {
01530       std->print_cr("true (0x%08x)", obj);
01531     } else if (obj == Universe::falseObj()) {
01532       std->print_cr("false (0x%08x)", obj);
01533     } else {
01534       std->print_cr("memOop (0x%08x)", obj);
01535     }
01536   } else {
01537     std->print_cr("0x%08x", obj);
01538   }
01539 }
01540 
01541 
01542 void MacroAssembler::inspector(oop edi, oop esi, oop ebp, oop esp, oop ebx, oop edx, oop ecx, oop eax, char* eip) {
01543   char* title = (char*)(nativeTest_at(eip)->data());
01544   if (title != NULL) std->print_cr("%s", title);
01545   print_reg("eax", eax);
01546   print_reg("ebx", ebx);
01547   print_reg("ecx", ecx);
01548   print_reg("edx", edx);
01549   print_reg("edi", edi);
01550   print_reg("esi", esi);
01551   std->print_cr("ebp = 0x%08x", ebp);
01552   std->print_cr("esp = 0x%08x", esp);
01553   std->cr();
01554 }
01555 
01556 
01557 void MacroAssembler::inspect(char* title) {
01558   char* entry = StubRoutines::call_inspector_entry();
01559   if (entry != NULL) {
01560     call(entry, relocInfo::runtime_call_type);                  // call stub invoking the inspector
01561     testl(eax, int(title));                                     // additional info for inspector
01562   } else {
01563     char* s = (title == NULL) ? "" : title;
01564     std->print_cr("cannot call inspector for \"%s\" - no entry point yet", s);
01565   }
01566 }

Generated on Mon Oct 9 13:37:01 2006 for Strongtalk VM by  doxygen 1.4.7