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 };