00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 const int nofRegisters = 8;     
00025 
00026 class Register: public ValueObj {
00027  private:
00028   int _number;
00029   
00030  public:
00031   
00032   Register(void): _number(-1)                   {}
00033   Register(int number, char f): _number(number) {}      
00034                                                         
00035                                                         
00036 
00037   
00038   int number() const            { assert(isValid(), "not a register"); return _number; }
00039   bool isValid() const          { return (0 <= _number) && (_number < nofRegisters); }
00040   bool hasByteRegister() const  { return 0 <= _number && _number <= 3; }
00041 
00042   
00043   friend bool operator == (Register x, Register y) { return x._number == y._number; }
00044   friend bool operator != (Register x, Register y) { return x._number != y._number; }
00045 
00046   
00047   char* name() const;
00048 };
00049 
00050 
00051 
00052 const Register eax = Register(0, ' ');
00053 const Register ecx = Register(1, ' ');
00054 const Register edx = Register(2, ' ');
00055 const Register ebx = Register(3, ' ');
00056 const Register esp = Register(4, ' ');
00057 const Register ebp = Register(5, ' ');
00058 const Register esi = Register(6, ' ');
00059 const Register edi = Register(7, ' ');
00060 const Register noreg; 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 class Label : public ValueObj {
00069  private:
00070   
00071   
00072   
00073   
00074   
00075   
00076   int _pos;
00077 
00078   int pos() const {
00079     if (_pos < 0) return -_pos - 1;
00080     if (_pos > 0) return  _pos - 1;
00081     ShouldNotReachHere();
00082     return 0;
00083   }
00084 
00085   void bind_to(int pos)         { assert(pos >= 0, "illegal position"); _pos = -pos - 1; }
00086   void link_to(int pos)         { assert(pos >= 0, "illegal position"); _pos =  pos + 1; }
00087   void unuse()                  { _pos = 0; }
00088 
00089  public:
00090   bool is_bound() const         { return _pos <  0; }
00091   bool is_unbound() const       { return _pos >  0; }
00092   bool is_unused() const        { return _pos == 0; }
00093 
00094   Label() : _pos(0)             {}
00095   ~Label()                      { assert(!is_unbound(), "unbound label"); }
00096 
00097   friend class Assembler;
00098   friend class MacroAssembler;
00099   friend class Displacement;
00100 };
00101 
00102 
00103 
00104 
00105 class Address: public ValueObj {
00106  public:
00107   enum ScaleFactor {
00108     no_scale    = -1,
00109     times_1     =  0,
00110     times_2     =  1,
00111     times_4     =  2,
00112     times_8     =  3
00113   };
00114 
00115  private:
00116   Register              _base;
00117   Register              _index;
00118   ScaleFactor           _scale;
00119   int                   _disp;
00120   relocInfo::relocType  _rtype;
00121 
00122  public:
00123   Address();
00124   Address(int disp, relocInfo::relocType rtype);
00125   Address(Register base, int disp = 0, relocInfo::relocType rtype = relocInfo::none);
00126   Address(Register base, Register index, ScaleFactor scale, int disp = 0, relocInfo::relocType rtype = relocInfo::none);
00127 
00128   friend class Assembler;
00129 };
00130 
00131 
00132 
00133 
00134 class Assembler: public ResourceObj {
00135  protected:
00136   CodeBuffer* _code;
00137 
00138   char* _code_begin;                    
00139   char* _code_limit;                    
00140   char* _code_pos;                      
00141 
00142   Label _unbound_label;                 
00143   int   _binding_pos;                   
00144 
00145   char* addr_at(int pos)                { return _code_begin + pos; }
00146 
00147   int  byte_at(int pos)                 { return *(unsigned char*)addr_at(pos); }
00148   void byte_at_put(int pos, int x)      { *(unsigned char*)addr_at(pos) = (unsigned char)x; }
00149 
00150   int  long_at(int pos)                 { return *(int*)addr_at(pos); }
00151   void long_at_put(int pos, int x)      { *(int*)addr_at(pos) = x; }
00152 
00153   bool is8bit(int x)                    { return -0x80 <= x && x < 0x80; }
00154   bool isByte(int x)                    { return 0 <= x && x < 0x100; }
00155   bool isShiftCount(int x)              { return 0 <= x && x < 32; }
00156 
00157   inline void emit_byte(int x);
00158   inline void emit_long(int x);
00159   inline void emit_data(int data, relocInfo::relocType rtype);
00160 
00161   void emit_arith_b(int op1, int op2, Register dst, int imm8);
00162 
00163   void emit_arith(int op1, int op2, Register dst, int imm32);
00164   void emit_arith(int op1, int op2, Register dst, oop obj);
00165   void emit_arith(int op1, int op2, Register dst, Register src);
00166 
00167   void emit_operand(Register reg, Register base, Register index, Address::ScaleFactor scale, int disp, relocInfo::relocType rtype);
00168   void emit_operand(Register reg, Address adr);
00169 
00170   void emit_farith(int b1, int b2, int i);
00171 
00172   void print  (Label& L);
00173   void bind_to(Label& L, int pos);
00174   void link_to(Label& L, Label& appendix);
00175 
00176  public:
00177   enum Condition {
00178     zero        = 0x4,
00179     notZero     = 0x5,
00180     equal       = 0x4,
00181     notEqual    = 0x5,
00182     less        = 0xc,
00183     lessEqual   = 0xe,
00184     greater     = 0xf,
00185     greaterEqual= 0xd,
00186     below       = 0x2,
00187     belowEqual  = 0x6,
00188     above       = 0x7,
00189     aboveEqual  = 0x3,
00190     overflow    = 0x0,
00191     noOverflow  = 0x1,
00192     carrySet    = 0x2,
00193     carryClear  = 0x3,
00194     negative    = 0x8,
00195     positive    = 0x9,
00196   };
00197 
00198   enum Constants {
00199     sizeOfCall = 5                      
00200   };
00201 
00202   Assembler(CodeBuffer* code);
00203 
00204   void          finalize();             
00205   CodeBuffer*   code() const            { return _code; }
00206   char*         pc() const              { return _code_pos; }
00207   int           offset() const          { return _code_pos - _code_begin; }
00208 
00209   
00210   void pushad();
00211   void popad();
00212 
00213   void pushl(int imm32);
00214   void pushl(oop obj);
00215   void pushl(Register src);
00216   void pushl(Address src);
00217 
00218   void popl(Register dst);
00219   void popl(Address dst);
00220 
00221   
00222   void movb(Register dst, Address src);
00223   void movb(Address dst, int imm8);
00224   void movb(Address dst, Register src);
00225 
00226   void movw(Register dst, Address src);
00227   void movw(Address dst, Register src);
00228 
00229   void movl(Register dst, int imm32);
00230   void movl(Register dst, oop obj);
00231   void movl(Register dst, Register src);
00232   void movl(Register dst, Address src);
00233 
00234   void movl(Address dst, int imm32);
00235   void movl(Address dst, oop obj);
00236   void movl(Address dst, Register src);
00237 
00238   void movsxb(Register dst, Address src);
00239   void movsxb(Register dst, Register src);
00240 
00241   void movsxw(Register dst, Address src);
00242   void movsxw(Register dst, Register src);
00243 
00244   
00245   void cmovccl(Condition cc, Register dst, int imm32);
00246   void cmovccl(Condition cc, Register dst, oop obj);
00247   void cmovccl(Condition cc, Register dst, Register src);
00248   void cmovccl(Condition cc, Register dst, Address src);
00249 
00250   
00251   void adcl(Register dst, int imm32);
00252   void adcl(Register dst, Register src);
00253 
00254   void addl(Address dst, int imm32);
00255   void addl(Register dst, int imm32);
00256   void addl(Register dst, Register src);
00257 
00258   void andl(Register dst, int imm32);
00259   void andl(Register dst, Register src);
00260 
00261   void cmpl(Address dst, int imm32);
00262   void cmpl(Address dst, oop obj);
00263   void cmpl(Register dst, int imm32);
00264   void cmpl(Register dst, oop obj);
00265   void cmpl(Register dst, Register src);
00266   void cmpl(Register dst, Address src);
00267 
00268   void decb(Register dst);
00269   void decl(Register dst);
00270 
00271   void idivl(Register src);
00272 
00273   void imull(Register dst, Register src);
00274   void imull(Register dst, Register src, int value);
00275 
00276   void incl(Register dst);
00277   void incl(Address dst);
00278 
00279   void leal(Register dst, Address src);
00280 
00281   void mull(Register src);
00282 
00283   void negl(Register dst);
00284 
00285   void notl(Register dst);
00286 
00287   void orl(Register dst, int imm32);
00288   void orl(Register dst, Register src);
00289   void orl(Register dst, Address src);
00290 
00291   void rcll(Register dst, int imm8);
00292 
00293   void sarl(Register dst, int imm8);
00294   void sarl(Register dst);
00295 
00296   void sbbl(Register dst, int imm32);
00297   void sbbl(Register dst, Register src);
00298 
00299   void shldl(Register dst, Register src);
00300 
00301   void shll(Register dst, int imm8);
00302   void shll(Register dst);
00303 
00304   void shrdl(Register dst, Register src);
00305 
00306   void shrl(Register dst, int imm8);
00307   void shrl(Register dst);
00308 
00309   void subl(Register dst, int imm32);
00310   void subl(Register dst, Register src);
00311 
00312   void testb(Register dst, int imm8);
00313   void testl(Register dst, int imm32);
00314   void testl(Register dst, Register src);
00315 
00316   void xorl(Register dst, int imm32);
00317   void xorl(Register dst, Register src);
00318 
00319   
00320   void hlt();
00321   void int3();
00322   void nop();
00323   void ret(int imm16);
00324 
00325   
00326 
00327   void bind(Label& L);                  
00328   void merge(Label& L, Label& with);    
00329 
00330   
00331   void call(Label& L);
00332   void call(char* entry, relocInfo::relocType rtype);
00333   void call(Register reg);
00334   void call(Address adr);
00335   
00336   
00337   void jmp(char* entry, relocInfo::relocType rtype);
00338   void jmp(Register reg);
00339   void jmp(Address adr);
00340 
00341   
00342   void jmp(Label& L);           
00343 
00344   
00345   
00346   
00347   
00348   
00349   
00350   
00351   
00352   
00353   
00354   
00355   
00356   
00357   
00358 
00359   void jcc(Condition cc, char* dst, relocInfo::relocType rtype = relocInfo::runtime_call_type);
00360   void jcc(Condition cc, Label& L);
00361 
00362   
00363   void ic_info(Label& L, int flags);
00364   
00365   
00366   void fld1();
00367   void fldz();
00368 
00369   void fld_s(Address adr);
00370   void fld_d(Address adr);
00371 
00372   void fstp_s(Address adr);
00373   void fstp_d(Address adr);
00374 
00375   void fild_s(Address adr);
00376   void fild_d(Address adr);
00377 
00378   void fistp_s(Address adr);
00379   void fistp_d(Address adr);
00380 
00381   void fabs();
00382   void fchs();
00383 
00384   void fadd(int i);
00385   void fsub(int i);
00386   void fmul(int i);
00387   void fdiv(int i);
00388 
00389   void faddp(int i = 1);
00390   void fsubp(int i = 1);
00391   void fsubrp(int i = 1);
00392   void fmulp(int i = 1);
00393   void fdivp(int i = 1);
00394   void fprem();
00395   void fprem1();
00396 
00397   void fxch(int i = 1);
00398   void fincstp();
00399   void ffree(int i = 0);
00400 
00401   void ftst();
00402   void fcompp();
00403   void fnstsw_ax();
00404   void fwait();
00405 
00406   
00407   void Load (Register base, int disp, Register dst) { movl(dst, Address(base, disp)); }
00408   void Store(Register src, Register base, int disp) { movl(Address(base, disp), src); }
00409 };
00410 
00411 
00412 
00413 
00414 
00415 class MacroAssembler: public Assembler {
00416  public:
00417   MacroAssembler(CodeBuffer* code) : Assembler(code) {}
00418 
00419   
00420   void align(int modulus);
00421 
00422   
00423   void test (Register dst, int imm8);           
00424   
00425   
00426   void enter();
00427   void leave();
00428 
00429   
00430 
00431   void inline_oop(oop o);
00432 
00433   
00434   void set_last_Delta_frame_before_call();      
00435   void set_last_Delta_frame_after_call();       
00436   void reset_last_Delta_frame();
00437 
00438   void call_C(Label& L);
00439   void call_C(Label& L, Label& nlrTestPoint);
00440 
00441   void call_C(char* entry, relocInfo::relocType rtype);
00442   void call_C(char* entry, relocInfo::relocType rtype, Label& nlrTestPoint);
00443 
00444   void call_C(Register entry);
00445   void call_C(Register entry, Label& nlrTestPoint);
00446 
00447   
00448   void call_C(char* entry, Register arg1);
00449   void call_C(char* entry, Register arg1, Register arg2);
00450   void call_C(char* entry, Register arg1, Register arg2, Register arg3);
00451   void call_C(char* entry, Register arg1, Register arg2, Register arg3, Register arg4);
00452 
00453   
00454   void store_check(Register obj, Register tmp);
00455 
00456   
00457   
00458   
00459   static void fpu_mask_and_cond_for(Condition cc, int& mask, Condition& cond);
00460 
00461   
00462   void fpop();
00463 
00464   
00465   static void print_reg(char* name, oop obj);
00466   static void inspector(oop edi, oop esi, oop ebp, oop esp, oop ebx, oop edx, oop ecx, oop eax, char* eip);
00467   void inspect(char* title = NULL);
00468 };