Mon, 25 Jul 2016 11:37:27 +0800
Add move conditional instructions (movz and movn) in MIPS assembler.
1 /*
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2015, 2016, Loongson Technology. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
26 #ifndef CPU_MIPS_VM_ASSEMBLER_MIPS_HPP
27 #define CPU_MIPS_VM_ASSEMBLER_MIPS_HPP
29 #include "asm/register.hpp"
31 class BiasedLockingCounters;
34 // Note: A register location is represented via a Register, not
35 // via an address for efficiency & simplicity reasons.
37 class ArrayAddress;
39 class Address VALUE_OBJ_CLASS_SPEC {
41 public:
42 enum ScaleFactor {
43 no_scale = -1,
44 times_1 = 0,
45 times_2 = 1,
46 times_4 = 2,
47 times_8 = 3,
48 times_ptr = LP64_ONLY(times_8) NOT_LP64(times_4)
49 };
51 static ScaleFactor times(int size) {
52 assert(size >= 1 && size <= 8 && is_power_of_2(size), "bad scale size");
53 if (size == 8) return times_8;
54 if (size == 4) return times_4;
55 if (size == 2) return times_2;
56 return times_1;
57 }
59 private:
60 Register _base;
61 Register _index;
62 ScaleFactor _scale;
63 int _disp;
64 RelocationHolder _rspec;
66 // Easily misused constructors make them private
67 // %%% can we make these go away?
68 //FIXME aoqi
69 //NOT_LP64(Address(address loc, RelocationHolder spec);)
70 Address(address loc, RelocationHolder spec);
71 Address(int disp, address loc, relocInfo::relocType rtype);
72 Address(int disp, address loc, RelocationHolder spec);
74 public:
76 int disp() { return _disp; }
77 // creation
78 Address()
79 : _base(noreg),
80 _index(noreg),
81 _scale(no_scale),
82 _disp(0) {
83 }
85 // No default displacement otherwise Register can be implicitly
86 // converted to 0(Register) which is quite a different animal.
88 Address(Register base, int disp)
89 : _base(base),
90 _index(noreg),
91 _scale(no_scale),
92 _disp(disp) {
93 }
95 Address(Register base)
96 : _base(base),
97 _index(noreg),
98 _scale(no_scale),
99 _disp(0) {
100 }
102 Address(Register base, Register index, ScaleFactor scale, int disp = 0)
103 : _base (base),
104 _index(index),
105 _scale(scale),
106 _disp (disp) {
107 assert(!index->is_valid() == (scale == Address::no_scale),
108 "inconsistent address");
109 }
111 // The following two overloads are used in connection with the
112 // ByteSize type (see sizes.hpp). They simplify the use of
113 // ByteSize'd arguments in assembly code. Note that their equivalent
114 // for the optimized build are the member functions with int disp
115 // argument since ByteSize is mapped to an int type in that case.
116 //
117 // Note: DO NOT introduce similar overloaded functions for WordSize
118 // arguments as in the optimized mode, both ByteSize and WordSize
119 // are mapped to the same type and thus the compiler cannot make a
120 // distinction anymore (=> compiler errors).
122 #ifdef ASSERT
123 Address(Register base, ByteSize disp)
124 : _base(base),
125 _index(noreg),
126 _scale(no_scale),
127 _disp(in_bytes(disp)) {
128 }
130 Address(Register base, Register index, ScaleFactor scale, ByteSize disp)
131 : _base(base),
132 _index(index),
133 _scale(scale),
134 _disp(in_bytes(disp)) {
135 assert(!index->is_valid() == (scale == Address::no_scale),
136 "inconsistent address");
137 }
138 #endif // ASSERT
140 // accessors
141 bool uses(Register reg) const { return _base == reg || _index == reg; }
142 Register base() const { return _base; }
143 Register index() const { return _index; }
144 ScaleFactor scale() const { return _scale; }
145 int disp() const { return _disp; }
147 // Convert the raw encoding form into the form expected by the constructor for
148 // Address. An index of 4 (rsp) corresponds to having no index, so convert
149 // that to noreg for the Address constructor.
150 //static Address make_raw(int base, int index, int scale, int disp);
152 static Address make_array(ArrayAddress);
154 /*
155 private:
156 bool base_needs_rex() const {
157 return _base != noreg && _base->encoding() >= 8;
158 }
160 bool index_needs_rex() const {
161 return _index != noreg &&_index->encoding() >= 8;
162 }
164 relocInfo::relocType reloc() const { return _rspec.type(); }
165 */
166 friend class Assembler;
167 friend class MacroAssembler;
168 friend class LIR_Assembler; // base/index/scale/disp
169 };
172 // Calling convention
173 class Argument VALUE_OBJ_CLASS_SPEC {
174 private:
175 int _number;
176 public:
177 enum {
178 #ifdef _LP64
179 n_register_parameters = 8, // 8 integer registers used to pass parameters
180 n_float_register_parameters = 8 // 4 float registers used to pass parameters
181 #else
182 n_register_parameters = 4, // 4 integer registers used to pass parameters
183 n_float_register_parameters = 4 // 4 float registers used to pass parameters
184 #endif
185 };
187 Argument(int number):_number(number){ }
188 Argument successor() {return Argument(number() + 1);}
190 int number()const {return _number;}
191 bool is_Register()const {return _number < n_register_parameters;}
192 bool is_FloatRegister()const {return _number < n_float_register_parameters;}
194 Register as_Register()const {
195 assert(is_Register(), "must be a register argument");
196 return ::as_Register(A0->encoding() + _number);
197 }
198 FloatRegister as_FloatRegister()const {
199 assert(is_FloatRegister(), "must be a float register argument");
200 return ::as_FloatRegister(F12->encoding() + _number);
201 }
203 Address as_caller_address()const {return Address(SP, (number() LP64_ONLY( -n_register_parameters)) * wordSize);}
204 };
208 //
209 // AddressLiteral has been split out from Address because operands of this type
210 // need to be treated specially on 32bit vs. 64bit platforms. By splitting it out
211 // the few instructions that need to deal with address literals are unique and the
212 // MacroAssembler does not have to implement every instruction in the Assembler
213 // in order to search for address literals that may need special handling depending
214 // on the instruction and the platform. As small step on the way to merging i486/amd64
215 // directories.
216 //
217 class AddressLiteral VALUE_OBJ_CLASS_SPEC {
218 friend class ArrayAddress;
219 RelocationHolder _rspec;
220 // Typically we use AddressLiterals we want to use their rval
221 // However in some situations we want the lval (effect address) of the item.
222 // We provide a special factory for making those lvals.
223 bool _is_lval;
225 // If the target is far we'll need to load the ea of this to
226 // a register to reach it. Otherwise if near we can do rip
227 // relative addressing.
229 address _target;
231 protected:
232 // creation
233 AddressLiteral()
234 : _is_lval(false),
235 _target(NULL)
236 {}
238 public:
240 AddressLiteral(address target, relocInfo::relocType rtype);
242 AddressLiteral(address target, RelocationHolder const& rspec)
243 : _rspec(rspec),
244 _is_lval(false),
245 _target(target)
246 {}
247 #ifdef _LP64
248 // 32-bit complains about a multiple declaration for int*.
249 AddressLiteral(intptr_t* addr, relocInfo::relocType rtype = relocInfo::none)
250 : _target((address) addr),
251 _rspec(rspec_from_rtype(rtype, (address) addr)) {}
252 #endif
255 AddressLiteral addr() {
256 AddressLiteral ret = *this;
257 ret._is_lval = true;
258 return ret;
259 }
262 private:
264 address target() { return _target; }
265 bool is_lval() { return _is_lval; }
267 relocInfo::relocType reloc() const { return _rspec.type(); }
268 const RelocationHolder& rspec() const { return _rspec; }
270 friend class Assembler;
271 friend class MacroAssembler;
272 friend class Address;
273 friend class LIR_Assembler;
274 RelocationHolder rspec_from_rtype(relocInfo::relocType rtype, address addr) {
275 switch (rtype) {
276 case relocInfo::external_word_type:
277 return external_word_Relocation::spec(addr);
278 case relocInfo::internal_word_type:
279 return internal_word_Relocation::spec(addr);
280 case relocInfo::opt_virtual_call_type:
281 return opt_virtual_call_Relocation::spec();
282 case relocInfo::static_call_type:
283 return static_call_Relocation::spec();
284 case relocInfo::runtime_call_type:
285 return runtime_call_Relocation::spec();
286 case relocInfo::poll_type:
287 case relocInfo::poll_return_type:
288 return Relocation::spec_simple(rtype);
289 case relocInfo::none:
290 case relocInfo::oop_type:
291 // Oops are a special case. Normally they would be their own section
292 // but in cases like icBuffer they are literals in the code stream that
293 // we don't have a section for. We use none so that we get a literal address
294 // which is always patchable.
295 return RelocationHolder();
296 default:
297 ShouldNotReachHere();
298 return RelocationHolder();
299 }
300 }
302 };
304 // Convience classes
305 class RuntimeAddress: public AddressLiteral {
307 public:
309 RuntimeAddress(address target) : AddressLiteral(target, relocInfo::runtime_call_type) {}
311 };
313 class OopAddress: public AddressLiteral {
315 public:
317 OopAddress(address target) : AddressLiteral(target, relocInfo::oop_type){}
319 };
321 class ExternalAddress: public AddressLiteral {
323 public:
325 ExternalAddress(address target) : AddressLiteral(target, relocInfo::external_word_type){}
327 };
329 class InternalAddress: public AddressLiteral {
331 public:
333 InternalAddress(address target) : AddressLiteral(target, relocInfo::internal_word_type) {}
335 };
337 // x86 can do array addressing as a single operation since disp can be an absolute
338 // address amd64 can't. We create a class that expresses the concept but does extra
339 // magic on amd64 to get the final result
341 class ArrayAddress VALUE_OBJ_CLASS_SPEC {
342 private:
344 AddressLiteral _base;
345 Address _index;
347 public:
349 ArrayAddress() {};
350 ArrayAddress(AddressLiteral base, Address index): _base(base), _index(index) {};
351 AddressLiteral base() { return _base; }
352 Address index() { return _index; }
354 };
356 const int FPUStateSizeInWords = NOT_LP64(27) LP64_ONLY( 512 / wordSize);
358 // The MIPS LOONGSON Assembler: Pure assembler doing NO optimizations on the instruction
359 // level ; i.e., what you write is what you get. The Assembler is generating code into
360 // a CodeBuffer.
362 class Assembler : public AbstractAssembler {
363 friend class AbstractAssembler; // for the non-virtual hack
364 friend class LIR_Assembler; // as_Address()
365 friend class StubGenerator;
367 public:
368 enum ops {
369 special_op = 0x00,
370 regimm_op = 0x01,
371 j_op = 0x02,
372 jal_op = 0x03,
373 beq_op = 0x04,
374 bne_op = 0x05,
375 blez_op = 0x06,
376 bgtz_op = 0x07,
377 addi_op = 0x08,
378 addiu_op = 0x09,
379 slti_op = 0x0a,
380 sltiu_op = 0x0b,
381 andi_op = 0x0c,
382 ori_op = 0x0d,
383 xori_op = 0x0e,
384 lui_op = 0x0f,
385 cop0_op = 0x10,
386 cop1_op = 0x11,
387 cop2_op = 0x12,
388 cop3_op = 0x13,
389 beql_op = 0x14,
390 bnel_op = 0x15,
391 blezl_op = 0x16,
392 bgtzl_op = 0x17,
393 daddi_op = 0x18,
394 daddiu_op = 0x19,
395 ldl_op = 0x1a,
396 ldr_op = 0x1b,
397 lb_op = 0x20,
398 lh_op = 0x21,
399 lwl_op = 0x22,
400 lw_op = 0x23,
401 lbu_op = 0x24,
402 lhu_op = 0x25,
403 lwr_op = 0x26,
404 lwu_op = 0x27,
405 sb_op = 0x28,
406 sh_op = 0x29,
407 swl_op = 0x2a,
408 sw_op = 0x2b,
409 sdl_op = 0x2c,
410 sdr_op = 0x2d,
411 swr_op = 0x2e,
412 cache_op = 0x2f,
413 ll_op = 0x30,
414 lwc1_op = 0x31,
415 lld_op = 0x34,
416 ldc1_op = 0x35,
417 ld_op = 0x37,
418 sc_op = 0x38,
419 swc1_op = 0x39,
420 scd_op = 0x3c,
421 sdc1_op = 0x3d,
422 sd_op = 0x3f
423 };
425 static const char *ops_name[];
427 //special family, the opcode is in low 6 bits.
428 enum special_ops {
429 sll_op = 0x00,
430 srl_op = 0x02,
431 sra_op = 0x03,
432 sllv_op = 0x04,
433 srlv_op = 0x06,
434 srav_op = 0x07,
435 jr_op = 0x08,
436 jalr_op = 0x09,
437 movz_op = 0x0a,
438 movn_op = 0x0b,
439 syscall_op = 0x0c,
440 break_op = 0x0d,
441 sync_op = 0x0f,
442 mfhi_op = 0x10,
443 mthi_op = 0x11,
444 mflo_op = 0x12,
445 mtlo_op = 0x13,
446 dsllv_op = 0x14,
447 dsrlv_op = 0x16,
448 dsrav_op = 0x17,
449 mult_op = 0x18,
450 multu_op = 0x19,
451 div_op = 0x1a,
452 divu_op = 0x1b,
453 dmult_op = 0x1c,
454 dmultu_op = 0x1d,
455 ddiv_op = 0x1e,
456 ddivu_op = 0x1f,
457 add_op = 0x20,
458 addu_op = 0x21,
459 sub_op = 0x22,
460 subu_op = 0x23,
461 and_op = 0x24,
462 or_op = 0x25,
463 xor_op = 0x26,
464 nor_op = 0x27,
465 slt_op = 0x2a,
466 sltu_op = 0x2b,
467 dadd_op = 0x2c,
468 daddu_op = 0x2d,
469 dsub_op = 0x2e,
470 dsubu_op = 0x2f,
471 tge_op = 0x30,
472 tgeu_op = 0x31,
473 tlt_op = 0x32,
474 tltu_op = 0x33,
475 teq_op = 0x34,
476 tne_op = 0x36,
477 dsll_op = 0x38,
478 dsrl_op = 0x3a,
479 dsra_op = 0x3b,
480 dsll32_op = 0x3c,
481 dsrl32_op = 0x3e,
482 dsra32_op = 0x3f
483 };
485 static const char* special_name[];
487 //regimm family, the opcode is in rt[16...20], 5 bits
488 enum regimm_ops {
489 bltz_op = 0x00,
490 bgez_op = 0x01,
491 bltzl_op = 0x02,
492 bgezl_op = 0x03,
493 tgei_op = 0x08,
494 tgeiu_op = 0x09,
495 tlti_op = 0x0a,
496 tltiu_op = 0x0b,
497 teqi_op = 0x0c,
498 tnei_op = 0x0e,
499 bltzal_op = 0x10,
500 bgezal_op = 0x11,
501 bltzall_op = 0x12,
502 bgezall_op = 0x13,
503 };
505 static const char* regimm_name[];
507 //copx family,the op in rs, 5 bits
508 enum cop_ops {
509 mf_op = 0x00,
510 dmf_op = 0x01,
511 cf_op = 0x02,
512 mt_op = 0x04,
513 dmt_op = 0x05,
514 ct_op = 0x06,
515 bc_op = 0x08,
516 single_fmt = 0x10,
517 double_fmt = 0x11,
518 word_fmt = 0x14,
519 long_fmt = 0x15
520 };
522 enum bc_ops {
523 bcf_op = 0x00,
524 bct_op = 0x01,
525 bcfl_op = 0x02,
526 bctl_op = 0x03,
527 };
529 enum c_conds {
530 f_cond = 0x30,
531 un_cond = 0x31,
532 eq_cond = 0x32,
533 ueq_cond = 0x33,
534 olt_cond = 0x34,
535 ult_cond = 0x35,
536 ole_cond = 0x36,
537 ule_cond = 0x37,
538 sf_cond = 0x38,
539 ngle_cond = 0x39,
540 seq_cond = 0x3a,
541 ngl_cond = 0x3b,
542 lt_cond = 0x3c,
543 nge_cond = 0x3d,
544 le_cond = 0x3e,
545 ngt_cond = 0x3f
546 };
548 //low 6 bits of cp1 instruction
549 enum float_ops {
550 fadd_op = 0x00,
551 fsub_op = 0x01,
552 fmul_op = 0x02,
553 fdiv_op = 0x03,
554 fsqrt_op = 0x04,
555 fabs_op = 0x05,
556 fmov_op = 0x06,
557 fneg_op = 0x07,
558 froundl_op = 0x08,
559 ftruncl_op = 0x09,
560 fceill_op = 0x0a,
561 ffloorl_op = 0x0b,
562 froundw_op = 0x0c,
563 ftruncw_op = 0x0d,
564 fceilw_op = 0x0e,
565 ffloorw_op = 0x0f,
566 fcvts_op = 0x20,
567 fcvtd_op = 0x21,
568 fcvtw_op = 0x24,
569 fcvtl_op = 0x25,
570 fpll_op =0x2c,
571 fplu_op =0x2d,
572 fpul_op =0x2e,
573 fpuu_op =0x2f,
575 };
577 /* 2013.10.16 Jin: merge from OpenJDK 8 */
578 enum WhichOperand {
579 // input to locate_operand, and format code for relocations
580 imm_operand = 0, // embedded 32-bit|64-bit immediate operand
581 disp32_operand = 1, // embedded 32-bit displacement or address
582 call32_operand = 2, // embedded 32-bit self-relative displacement
583 #ifndef _LP64
584 _WhichOperand_limit = 3
585 #else
586 narrow_oop_operand = 3, // embedded 32-bit immediate narrow oop
587 _WhichOperand_limit = 4
588 #endif
589 };
591 /* Godson3 extension */
592 enum godson3_ops {
593 gsldx_op = (0x36 << 26) | 0x3,
594 gslwx_op = (0x36 << 26) | 0x2,
595 };
597 static const char* float_name[];
599 static int opcode(int insn) { return (insn>>26)&0x3f; }
600 static int rs(int insn) { return (insn>>21)&0x1f; }
601 static int rt(int insn) { return (insn>>16)&0x1f; }
602 static int rd(int insn) { return (insn>>11)&0x1f; }
603 static int sa(int insn) { return (insn>>6)&0x1f; }
604 static int special(int insn) { return insn&0x3f; }
605 static int imm_off(int insn) { return (short)low16(insn); }
607 static int low (int x, int l) { return bitfield(x, 0, l); }
608 static int low16(int x) { return low(x, 16); }
609 static int low26(int x) { return low(x, 26); }
611 protected:
612 //help methods for instruction ejection
614 //I-Type (Immediate)
615 // 31 26 25 21 20 16 15 0
616 //| opcode | rs | rt | immediat |
617 //| | | | |
618 // 6 5 5 16
619 static int insn_ORRI(int op, int rs, int rt, int imm) { return (op<<26) | (rs<<21) | (rt<<16) | low16(imm); }
621 //R-Type (Register)
622 // 31 26 25 21 20 16 15 11 10 6 5 0
623 //| special | rs | rt | rd | 0 | opcode |
624 //| 0 0 0 0 0 0 | | | | 0 0 0 0 0 | |
625 // 6 5 5 5 5 6
626 static int insn_RRRO(int rs, int rt, int rd, int op) { return (rs<<21) | (rt<<16) | (rd<<11) | op; }
627 static int insn_RRSO(int rt, int rd, int sa, int op) { return (rt<<16) | (rd<<11) | (sa<<6) | op; }
628 static int insn_RRCO(int rs, int rt, int code, int op) { return (rs<<21) | (rt<<16) | (code<<6) | op; }
630 static int insn_COP0(int op, int rt, int rd) { return (cop0_op<<26) | (op<<21) | (rt<<16) | (rd<<11); }
631 static int insn_COP1(int op, int rt, int fs) { return (cop1_op<<26) | (op<<21) | (rt<<16) | (fs<<11); }
633 static int insn_F3RO(int fmt, int ft, int fs, int fd, int func) {
634 return (cop1_op<<26) | (fmt<<21) | (ft<<16) | (fs<<11) | (fd<<6) | func;
635 }
638 //static int low (int x, int l) { return bitfield(x, 0, l); }
639 //static int low16(int x) { return low(x, 16); }
640 //static int low26(int x) { return low(x, 26); }
642 static int high (int x, int l) { return bitfield(x, 32-l, l); }
643 static int high16(int x) { return high(x, 16); }
644 static int high6 (int x) { return high(x, 6); }
646 //get the offset field of jump/branch instruction
647 int offset(address entry) {
648 assert(is_simm16((entry - pc() - 4) / 4), "change this code");
649 if (!is_simm16((entry - pc() - 4) / 4)) {
650 tty->print_cr("!!! is_simm16: %x", (entry - pc() - 4) / 4);
651 }
652 return (entry - pc() - 4) / 4;
653 }
656 public:
657 using AbstractAssembler::offset;
659 //sign expand with the sign bit is h
660 static int expand(int x, int h) { return -(x & (1<<h)) | x; }
662 // mips lui/addiu is both sign extended, so if you wan't to use off32/imm32, you have to use the follow three
663 // by yjl 6/22/2005
664 static int split_low(int x) {
665 return (x & 0xffff);
666 }
668 static int split_high(int x) {
669 return ( (x >> 16) + ((x & 0x8000) != 0) ) & 0xffff;
670 }
672 static int merge(int low, int high) {
673 return expand(low, 15) + (high<<16);
674 }
676 #ifdef _LP64
677 static intptr_t merge(intptr_t x0, intptr_t x16, intptr_t x32, intptr_t x48) {
678 return (x48 << 48) | (x32 << 32) | (x16 << 16) | x0;
679 /*
680 return ((intptr_t)(long_at(0) & 0xffff) << 48)
681 + expand((intptr_t)(long_at(4) & 0xffff) << 32, 47)
682 + expand((intptr_t)(long_at(12) & 0xffff) << 16, 31)
683 + expand((intptr_t)(long_at(20) & 0xffff), 15);
684 return expand(low, 15) + (high<<16);
685 */
686 }
687 #endif
689 // modified by spark 2005/08/18
690 static bool is_simm (int x, int nbits) { return -( 1 << nbits-1 ) <= x && x < ( 1 << nbits-1 ); }
691 static bool is_simm16(int x) { return is_simm(x, 16); }
693 // test if imm can be coded in a instruction with 16-bit imm/off
694 // by yjl 6/23/2005
695 /*static bool fit_in_insn(int imm) {
696 return imm == (short)imm;
697 }*/
699 static bool fit_in_jal(int offset) {
700 return is_simm(offset, 26);
701 }
704 // test if entry can be filled in the jl/jal,
705 // must be used just before you emit jl/jal
706 // by yjl 6/27/2005
707 bool fit_int_jal(address entry) {
708 return fit_in_jal(offset(entry));
709 }
711 bool fit_int_branch(address entry) {
712 return is_simm16(offset(entry));
713 }
715 protected:
716 #ifdef ASSERT
717 #define CHECK_DELAY
718 #endif
719 #ifdef CHECK_DELAY
720 enum Delay_state { no_delay, at_delay_slot, filling_delay_slot } delay_state;
721 #endif
723 public:
724 void assert_not_delayed() {
725 #ifdef CHECK_DELAY
726 assert_not_delayed("next instruction should not be a delay slot");
727 #endif
728 }
730 void assert_not_delayed(const char* msg) {
731 #ifdef CHECK_DELAY
732 //guarantee( delay_state == no_delay, msg );
733 //aoqi_test
734 if(delay_state != no_delay){
735 tty->print_cr("%s:%d, pc: %lx", __func__, __LINE__, pc());
736 }
737 assert(delay_state == no_delay, msg);
738 #endif
739 }
741 protected:
742 // Delay slot helpers
743 // cti is called when emitting control-transfer instruction,
744 // BEFORE doing the emitting.
745 // Only effective when assertion-checking is enabled.
747 // called when emitting cti with a delay slot, AFTER emitting
748 void has_delay_slot() {
749 #ifdef CHECK_DELAY
750 assert_not_delayed("just checking");
751 delay_state = at_delay_slot;
752 #endif
753 }
755 public:
756 Assembler* delayed() {
757 #ifdef CHECK_DELAY
758 guarantee( delay_state == at_delay_slot, "delayed instructition is not in delay slot");
759 delay_state = filling_delay_slot;
760 #endif
761 return this;
762 }
764 void flush() {
765 #ifdef CHECK_DELAY
766 guarantee( delay_state == no_delay, "ending code with a delay slot");
767 #endif
768 AbstractAssembler::flush();
769 }
771 inline void emit_long(int); // shadows AbstractAssembler::emit_long
772 inline void emit_data(int x) { emit_long(x); }
773 inline void emit_data(int, RelocationHolder const&);
774 inline void emit_data(int, relocInfo::relocType rtype);
775 inline void check_delay();
778 // Generic instructions
779 // Does 32bit or 64bit as needed for the platform. In some sense these
780 // belong in macro assembler but there is no need for both varieties to exist
782 #ifndef _LP64
783 void add(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), add_op)); }
784 void addi(Register rt, Register rs, int imm) { emit_long(insn_ORRI(addi_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
785 void addiu(Register rt, Register rs, int imm) { emit_long(insn_ORRI(addiu_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
786 void addu(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), addu_op)); }
787 #else
788 void add(Register rd, Register rs, Register rt) { dadd (rd, rs, rt); }
789 void add32(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), add_op)); }
790 void addu32(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), addu_op)); }
791 void addiu32(Register rt, Register rs, int imm) { emit_long(insn_ORRI(addiu_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
792 void addi(Register rt, Register rs, int imm) { daddi (rt, rs, imm);}
793 void addiu(Register rt, Register rs, int imm) { daddiu (rt, rs, imm);}
794 void addu(Register rd, Register rs, Register rt) { daddu (rd, rs, rt); }
795 #endif
797 void andr(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), and_op)); }
798 void andi(Register rt, Register rs, int imm) { emit_long(insn_ORRI(andi_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
800 void beq (Register rs, Register rt, int off) { emit_long(insn_ORRI(beq_op, (int)rs->encoding(), (int)rt->encoding(), off)); has_delay_slot(); }
801 void beql (Register rs, Register rt, int off) { emit_long(insn_ORRI(beql_op, (int)rs->encoding(), (int)rt->encoding(), off)); has_delay_slot(); }
802 void bgez (Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bgez_op, off)); has_delay_slot(); }
803 void bgezal (Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bgezal_op, off)); has_delay_slot(); }
804 void bgezall(Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bgezall_op, off)); has_delay_slot(); }
805 void bgezl (Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bgezl_op, off)); has_delay_slot(); }
806 void bgtz (Register rs, int off) { emit_long(insn_ORRI(bgtz_op, (int)rs->encoding(), 0, off)); has_delay_slot(); }
807 void bgtzl (Register rs, int off) { emit_long(insn_ORRI(bgtzl_op, (int)rs->encoding(), 0, off)); has_delay_slot(); }
808 void blez (Register rs, int off) { emit_long(insn_ORRI(blez_op, (int)rs->encoding(), 0, off)); has_delay_slot(); }
809 void blezl (Register rs, int off) { emit_long(insn_ORRI(blezl_op, (int)rs->encoding(), 0, off)); has_delay_slot(); }
810 void bltz (Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bltz_op, off)); has_delay_slot(); }
811 void bltzal (Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bltzal_op, off)); has_delay_slot(); }
812 void bltzall(Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bltzall_op, off)); has_delay_slot(); }
813 void bltzl (Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bltzl_op, off)); has_delay_slot(); }
814 void bne (Register rs, Register rt, int off) { emit_long(insn_ORRI(bne_op, (int)rs->encoding(), (int)rt->encoding(), off)); has_delay_slot(); }
815 void bnel (Register rs, Register rt, int off) { emit_long(insn_ORRI(bnel_op, (int)rs->encoding(), (int)rt->encoding(), off)); has_delay_slot(); }
816 void brk (int code) { emit_long(break_op | (code<<16)); }
818 void beq (Register rs, Register rt, address entry) { beq(rs, rt, offset(entry)); }
819 void beql (Register rs, Register rt, address entry) { beql(rs, rt, offset(entry));}
820 void bgez (Register rs, address entry) { bgez (rs, offset(entry)); }
821 void bgezal (Register rs, address entry) { bgezal (rs, offset(entry)); }
822 void bgezall(Register rs, address entry) { bgezall(rs, offset(entry)); }
823 void bgezl (Register rs, address entry) { bgezl (rs, offset(entry)); }
824 void bgtz (Register rs, address entry) { bgtz (rs, offset(entry)); }
825 void bgtzl (Register rs, address entry) { bgtzl (rs, offset(entry)); }
826 void blez (Register rs, address entry) { blez (rs, offset(entry)); }
827 void blezl (Register rs, address entry) { blezl (rs, offset(entry)); }
828 void bltz (Register rs, address entry) { bltz (rs, offset(entry)); }
829 void bltzal (Register rs, address entry) { bltzal (rs, offset(entry)); }
830 void bltzall(Register rs, address entry) { bltzall(rs, offset(entry)); }
831 void bltzl (Register rs, address entry) { bltzl (rs, offset(entry)); }
832 void bne (Register rs, Register rt, address entry) { bne(rs, rt, offset(entry)); }
833 void bnel (Register rs, Register rt, address entry) { bnel(rs, rt, offset(entry)); }
835 void beq (Register rs, Register rt, Label& L) { beq(rs, rt, target(L)); }
836 void beql (Register rs, Register rt, Label& L) { beql(rs, rt, target(L)); }
837 void bgez (Register rs, Label& L){ bgez (rs, target(L)); }
838 void bgezal (Register rs, Label& L){ bgezal (rs, target(L)); }
839 void bgezall(Register rs, Label& L){ bgezall(rs, target(L)); }
840 void bgezl (Register rs, Label& L){ bgezl (rs, target(L)); }
841 void bgtz (Register rs, Label& L){ bgtz (rs, target(L)); }
842 void bgtzl (Register rs, Label& L){ bgtzl (rs, target(L)); }
843 void blez (Register rs, Label& L){ blez (rs, target(L)); }
844 void blezl (Register rs, Label& L){ blezl (rs, target(L)); }
845 void bltz (Register rs, Label& L){ bltz (rs, target(L)); }
846 void bltzal (Register rs, Label& L){ bltzal (rs, target(L)); }
847 void bltzall(Register rs, Label& L){ bltzall(rs, target(L)); }
848 void bltzl (Register rs, Label& L){ bltzl (rs, target(L)); }
849 void bne (Register rs, Register rt, Label& L){ bne(rs, rt, target(L)); }
850 void bnel (Register rs, Register rt, Label& L){ bnel(rs, rt, target(L)); }
852 void dadd (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), dadd_op)); }
853 void daddi (Register rt, Register rs, int imm) { emit_long(insn_ORRI(daddi_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
854 void daddiu(Register rt, Register rs, int imm) { emit_long(insn_ORRI(daddiu_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
855 void daddu (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), daddu_op)); }
856 void ddiv (Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, ddiv_op)); }
857 void ddivu (Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, ddivu_op)); }
859 void movz (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), movz_op)); }
860 void movn (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), movn_op)); }
862 // Do mult and div need both 32-bit and 64-bit version? FIXME aoqi
863 //#ifndef _LP64
864 #if 1
865 void div (Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, div_op)); }
866 void divu (Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, divu_op)); }
867 #else
868 void div (Register rs, Register rt) { ddiv (rs, rt);}
869 void divu (Register rs, Register rt) { ddivu(rs, rt);}
870 #endif
871 void dmfc0 (Register rt, FloatRegister rd) { emit_long(insn_COP0(dmf_op, (int)rt->encoding(), (int)rd->encoding())); }
872 void dmtc0 (Register rt, FloatRegister rd) { emit_long(insn_COP0(dmt_op, (int)rt->encoding(), (int)rd->encoding())); }
873 void dmult (Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, dmult_op)); }
874 void dmultu(Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, dmultu_op)); }
875 void dsll (Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), sa, dsll_op)); }
876 void dsllv (Register rd, Register rt, Register rs) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), dsllv_op)); }
877 void dsll32(Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), sa, dsll32_op)); }
878 void dsra (Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), sa, dsra_op)); }
879 void dsrav (Register rd, Register rt, Register rs) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), dsrav_op)); }
880 void dsra32(Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), sa, dsra32_op)); }
881 void dsrl (Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), sa, dsrl_op)); }
882 void dsrlv (Register rd, Register rt, Register rs) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), dsrlv_op)); }
883 void dsrl32(Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), sa, dsrl32_op)); }
884 void dsub (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), dsub_op)); }
885 void dsubu (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), dsubu_op)); }
887 void b(int off) { beq(R0, R0, off); }
888 void b(address entry) { b(offset(entry)); }
889 void b(Label& L) { b(target(L)); }
891 void j(address entry);
892 void jal(address entry);
894 void jalr(Register rd, Register rs) { emit_long( ((int)rs->encoding()<<21) | ((int)rd->encoding()<<11) | jalr_op); has_delay_slot(); }
895 void jalr(Register rs) { jalr(RA, rs); }
896 void jalr() { jalr(T9); }
898 void jr(Register rs) { emit_long(((int)rs->encoding()<<21) | jr_op); has_delay_slot(); }
900 void lb (Register rt, Register base, int off) { emit_long(insn_ORRI(lb_op, (int)base->encoding(), (int)rt->encoding(), off)); }
901 void lbu(Register rt, Register base, int off) { emit_long(insn_ORRI(lbu_op, (int)base->encoding(), (int)rt->encoding(), off)); }
902 void ld (Register rt, Register base, int off) { emit_long(insn_ORRI(ld_op, (int)base->encoding(), (int)rt->encoding(), off)); }
903 void ldl(Register rt, Register base, int off) { emit_long(insn_ORRI(ldl_op, (int)base->encoding(), (int)rt->encoding(), off)); }
904 void ldr(Register rt, Register base, int off) { emit_long(insn_ORRI(ldr_op, (int)base->encoding(), (int)rt->encoding(), off)); }
905 void lh (Register rt, Register base, int off) { emit_long(insn_ORRI(lh_op, (int)base->encoding(), (int)rt->encoding(), off)); }
906 void lhu(Register rt, Register base, int off) { emit_long(insn_ORRI(lhu_op, (int)base->encoding(), (int)rt->encoding(), off)); }
907 void ll (Register rt, Register base, int off) { emit_long(insn_ORRI(ll_op, (int)base->encoding(), (int)rt->encoding(), off)); }
908 void lld(Register rt, Register base, int off) { emit_long(insn_ORRI(lld_op, (int)base->encoding(), (int)rt->encoding(), off)); }
909 void lui(Register rt, int imm) { emit_long(insn_ORRI(lui_op, 0, (int)rt->encoding(), imm)); }
910 void lw (Register rt, Register base, int off) { emit_long(insn_ORRI(lw_op, (int)base->encoding(), (int)rt->encoding(), off)); }
911 void lwl(Register rt, Register base, int off) { emit_long(insn_ORRI(lwl_op, (int)base->encoding(), (int)rt->encoding(), off)); }
912 void lwr(Register rt, Register base, int off) { emit_long(insn_ORRI(lwr_op, (int)base->encoding(), (int)rt->encoding(), off)); }
913 void lwu(Register rt, Register base, int off) { emit_long(insn_ORRI(lwu_op, (int)base->encoding(), (int)rt->encoding(), off)); }
915 void lb (Register rt, Address src);
916 void lbu(Register rt, Address src);
917 void ld (Register rt, Address src);
918 void ldl(Register rt, Address src);
919 void ldr(Register rt, Address src);
920 void lh (Register rt, Address src);
921 void lhu(Register rt, Address src);
922 void ll (Register rt, Address src);
923 void lld(Register rt, Address src);
924 void lw (Register rt, Address src);
925 void lwl(Register rt, Address src);
926 void lwr(Register rt, Address src);
927 void lwu(Register rt, Address src);
928 void lea(Register rt, Address src);
930 void mfc0 (Register rt, Register rd) { emit_long(insn_COP0(mf_op, (int)rt->encoding(), (int)rd->encoding())); }
931 void mfhi (Register rd) { emit_long( ((int)rd->encoding()<<11) | mfhi_op ); }
932 void mflo (Register rd) { emit_long( ((int)rd->encoding()<<11) | mflo_op ); }
933 void mtc0 (Register rt, Register rd) { emit_long(insn_COP0(mt_op, (int)rt->encoding(), (int)rd->encoding())); }
934 void mthi (Register rs) { emit_long( ((int)rs->encoding()<<21) | mthi_op ); }
935 void mtlo (Register rs) { emit_long( ((int)rs->encoding()<<21) | mtlo_op ); }
936 // Do mult and div need both 32-bit and 64-bit version? FIXME aoqi
937 //#ifndef _LP64
938 #if 1
939 void mult (Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, mult_op)); }
940 void multu(Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, multu_op)); }
941 #else
942 void mult (Register rs, Register rt) { dmult (rs, rt); }
943 void multu(Register rs, Register rt) { dmultu (rs, rt); }
944 #endif
946 void nor(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), nor_op)); }
948 void orr(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), or_op)); }
949 void ori(Register rt, Register rs, int imm) { emit_long(insn_ORRI(ori_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
951 void sb (Register rt, Register base, int off) { emit_long(insn_ORRI(sb_op, (int)base->encoding(), (int)rt->encoding(), off)); }
952 void sc (Register rt, Register base, int off) { emit_long(insn_ORRI(sc_op, (int)base->encoding(), (int)rt->encoding(), off)); }
953 void scd (Register rt, Register base, int off) { emit_long(insn_ORRI(scd_op, (int)base->encoding(), (int)rt->encoding(), off)); }
954 void sd (Register rt, Register base, int off) { emit_long(insn_ORRI(sd_op, (int)base->encoding(), (int)rt->encoding(), off)); }
955 void sdl (Register rt, Register base, int off) { emit_long(insn_ORRI(sdl_op, (int)base->encoding(), (int)rt->encoding(), off)); }
956 void sdr (Register rt, Register base, int off) { emit_long(insn_ORRI(sdr_op, (int)base->encoding(), (int)rt->encoding(), off)); }
957 void sh (Register rt, Register base, int off) { emit_long(insn_ORRI(sh_op, (int)base->encoding(), (int)rt->encoding(), off)); }
958 //#ifndef _LP64
959 #if 1
960 void sll (Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), sa, sll_op)); }
961 void sllv (Register rd, Register rt, Register rs) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), sllv_op)); }
962 #else
963 void sll (Register rd, Register rt , int sa) { dsll (rd, rt, sa);}
964 void sllv (Register rd, Register rt, Register rs) { dsllv (rd, rt, rs); }
965 #endif
966 void slt (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), slt_op)); }
967 void slti (Register rt, Register rs, int imm) { emit_long(insn_ORRI(slti_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
968 void sltiu(Register rt, Register rs, int imm) { emit_long(insn_ORRI(sltiu_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
969 void sltu (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), sltu_op)); }
970 //#ifndef _LP64
971 #if 1
972 void sra (Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), sa, sra_op)); }
973 void srav (Register rd, Register rt, Register rs) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), srav_op)); }
974 void srl (Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), sa, srl_op)); }
975 void srlv (Register rd, Register rt, Register rs) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), srlv_op)); }
976 #else
977 void sra (Register rd, Register rt , int sa) { dsra (rd, rt, sa); }
978 void srav (Register rd, Register rt, Register rs) { dsrav (rd, rt, rs); }
979 void srl (Register rd, Register rt , int sa) { dsrl (rd, rt, sa); }
980 void srlv (Register rd, Register rt, Register rs) { dsrlv (rd, rt, rs); }
981 #endif
982 #ifndef _LP64
983 void sub (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), sub_op)); }
984 void subu (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), subu_op)); }
985 #else
986 void sub (Register rd, Register rs, Register rt) { dsub (rd, rs, rt); }
987 void subu (Register rd, Register rs, Register rt) { dsubu (rd, rs, rt); }
988 void subu32 (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), subu_op)); }
989 #endif
990 void sw (Register rt, Register base, int off) { emit_long(insn_ORRI(sw_op, (int)base->encoding(), (int)rt->encoding(), off)); }
991 void swl (Register rt, Register base, int off) { emit_long(insn_ORRI(swl_op, (int)base->encoding(), (int)rt->encoding(), off)); }
992 void swr (Register rt, Register base, int off) { emit_long(insn_ORRI(swr_op, (int)base->encoding(), (int)rt->encoding(), off)); }
993 void sync () { emit_long(sync_op); }
994 void syscall(int code) { emit_long( (code<<6) | syscall_op ); }
996 void sb(Register rt, Address dst);
997 void sc(Register rt, Address dst);
998 void scd(Register rt, Address dst);
999 void sd(Register rt, Address dst);
1000 void sdl(Register rt, Address dst);
1001 void sdr(Register rt, Address dst);
1002 void sh(Register rt, Address dst);
1003 void sw(Register rt, Address dst);
1004 void swl(Register rt, Address dst);
1005 void swr(Register rt, Address dst);
1007 void teq (Register rs, Register rt, int code) { emit_long(insn_RRCO((int)rs->encoding(), (int)rt->encoding(), code, teq_op)); }
1008 void teqi (Register rs, int imm) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), teqi_op, imm)); }
1009 void tge (Register rs, Register rt, int code) { emit_long(insn_RRCO((int)rs->encoding(), (int)rt->encoding(), code, tge_op)); }
1010 void tgei (Register rs, int imm) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), tgei_op, imm)); }
1011 void tgeiu(Register rs, int imm) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), tgeiu_op, imm)); }
1012 void tgeu (Register rs, Register rt, int code) { emit_long(insn_RRCO((int)rs->encoding(), (int)rt->encoding(), code, tgeu_op)); }
1013 void tlt (Register rs, Register rt, int code) { emit_long(insn_RRCO((int)rs->encoding(), (int)rt->encoding(), code, tlt_op)); }
1014 void tlti (Register rs, int imm) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), tlti_op, imm)); }
1015 void tltiu(Register rs, int imm) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), tltiu_op, imm)); }
1016 void tltu (Register rs, Register rt, int code) { emit_long(insn_RRCO((int)rs->encoding(), (int)rt->encoding(), code, tltu_op)); }
1017 void tne (Register rs, Register rt, int code) { emit_long(insn_RRCO((int)rs->encoding(), (int)rt->encoding(), code, tne_op)); }
1018 void tnei (Register rs, int imm) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), tnei_op, imm)); }
1020 void xorr(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), xor_op)); }
1021 void xori(Register rt, Register rs, int imm) { emit_long(insn_ORRI(xori_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
1023 void nop() { emit_long(0); }
1024 //float instructions for mips
1025 void abs_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fabs_op));}
1026 void abs_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fabs_op));}
1027 void add_s(FloatRegister fd, FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), (int)fd->encoding(), fadd_op));}
1028 void add_d(FloatRegister fd, FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), (int)fd->encoding(), fadd_op));}
1030 void bc1f (int off) { emit_long(insn_ORRI(cop1_op, bc_op, bcf_op, off)); has_delay_slot(); }
1031 void bc1fl(int off) { emit_long(insn_ORRI(cop1_op, bc_op, bcfl_op, off)); has_delay_slot(); }
1032 void bc1t (int off) { emit_long(insn_ORRI(cop1_op, bc_op, bct_op, off)); has_delay_slot(); }
1033 void bc1tl(int off) { emit_long(insn_ORRI(cop1_op, bc_op, bctl_op, off)); has_delay_slot(); }
1035 void bc1f (address entry) { bc1f(offset(entry)); }
1036 void bc1fl(address entry) { bc1fl(offset(entry)); }
1037 void bc1t (address entry) { bc1t(offset(entry)); }
1038 void bc1tl(address entry) { bc1tl(offset(entry)); }
1040 void bc1f (Label& L) { bc1f(target(L)); }
1041 void bc1fl(Label& L) { bc1fl(target(L)); }
1042 void bc1t (Label& L) { bc1t(target(L)); }
1043 void bc1tl(Label& L) { bc1tl(target(L)); }
1045 void c_f_s (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, f_cond)); }
1046 void c_f_d (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, f_cond)); }
1047 void c_un_s (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, un_cond)); }
1048 void c_un_d (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, un_cond)); }
1049 void c_eq_s (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, eq_cond)); }
1050 void c_eq_d (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, eq_cond)); }
1051 void c_ueq_s (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ueq_cond)); }
1052 void c_ueq_d (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ueq_cond)); }
1053 void c_olt_s (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, olt_cond)); }
1054 void c_olt_d (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, olt_cond)); }
1055 void c_ult_s (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ult_cond)); }
1056 void c_ult_d (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ult_cond)); }
1057 void c_ole_s (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ole_cond)); }
1058 void c_ole_d (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ole_cond)); }
1059 void c_ule_s (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ule_cond)); }
1060 void c_ule_d (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ule_cond)); }
1061 void c_sf_s (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, sf_cond)); }
1062 void c_sf_d (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, sf_cond)); }
1063 void c_ngle_s(FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ngle_cond)); }
1064 void c_ngle_d(FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ngle_cond)); }
1065 void c_seq_s (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, seq_cond)); }
1066 void c_seq_d (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, seq_cond)); }
1067 void c_ngl_s (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ngl_cond)); }
1068 void c_ngl_d (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ngl_cond)); }
1069 void c_lt_s (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, lt_cond)); }
1070 void c_lt_d (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, lt_cond)); }
1071 void c_nge_s (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, nge_cond)); }
1072 void c_nge_d (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, nge_cond)); }
1073 void c_le_s (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, le_cond)); }
1074 void c_le_d (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, le_cond)); }
1075 void c_ngt_s (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ngt_cond)); }
1076 void c_ngt_d (FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), 0, ngt_cond)); }
1078 void ceil_l_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fceill_op)); }
1079 void ceil_l_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fceill_op)); }
1080 void ceil_w_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fceilw_op)); }
1081 void ceil_w_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fceilw_op)); }
1082 void cfc1(Register rt, FloatRegister fs) { emit_long(insn_COP1(cf_op, (int)rt->encoding(), (int)fs->encoding())); }
1083 void ctc1(Register rt, FloatRegister fs) { emit_long(insn_COP1(ct_op, (int)rt->encoding(), (int)fs->encoding())); }
1084 void cfc1(Register rt, int fs) { emit_long(insn_COP1(cf_op, (int)rt->encoding(), fs)); }
1085 void ctc1(Register rt, int fs) { emit_long(insn_COP1(ct_op, (int)rt->encoding(), fs)); }
1087 void cvt_d_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvtd_op)); }
1088 void cvt_d_w(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(word_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvtd_op)); }
1089 void cvt_d_l(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(long_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvtd_op)); }
1090 void cvt_l_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvtl_op)); }
1091 void cvt_l_w(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(word_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvtl_op)); }
1092 void cvt_l_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvtl_op)); }
1093 void cvt_s_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvts_op)); }
1094 void cvt_s_w(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(word_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvts_op)); }
1095 void cvt_s_l(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(long_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvts_op)); }
1096 void cvt_w_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvtw_op)); }
1097 void cvt_w_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvtw_op)); }
1098 void cvt_w_l(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(long_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvtw_op)); }
1099 void pll(FloatRegister fd, FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(long_fmt, (int)ft->encoding(), (int)fs->encoding(), (int)fd->encoding(), fpll_op)); }
1100 void plu(FloatRegister fd, FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(long_fmt, (int)ft->encoding(), (int)fs->encoding(), (int)fd->encoding(), fplu_op)); }
1101 void pul(FloatRegister fd, FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(long_fmt, (int)ft->encoding(), (int)fs->encoding(), (int)fd->encoding(), fpul_op)); }
1102 void puu(FloatRegister fd, FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(long_fmt, (int)ft->encoding(), (int)fs->encoding(), (int)fd->encoding(), fpuu_op)); }
1104 void div_s(FloatRegister fd, FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), (int)fd->encoding(), fdiv_op)); }
1105 void div_d(FloatRegister fd, FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), (int)fd->encoding(), fdiv_op)); }
1106 void dmfc1(Register rt, FloatRegister fs) { emit_long(insn_COP1(dmf_op, (int)rt->encoding(), (int)fs->encoding())); }
1107 void dmtc1(Register rt, FloatRegister fs) { emit_long(insn_COP1(dmt_op, (int)rt->encoding(), (int)fs->encoding())); }
1109 void floor_l_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), ffloorl_op)); }
1110 void floor_l_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), ffloorl_op)); }
1111 void floor_w_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), ffloorw_op)); }
1112 void floor_w_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), ffloorw_op)); }
1114 void ldc1(FloatRegister ft, Register base, int off) { emit_long(insn_ORRI(ldc1_op, (int)base->encoding(), (int)ft->encoding(), off)); }
1115 void lwc1(FloatRegister ft, Register base, int off) { emit_long(insn_ORRI(lwc1_op, (int)base->encoding(), (int)ft->encoding(), off)); }
1116 void ldc1(FloatRegister ft, Address src);
1117 void lwc1(FloatRegister ft, Address src);
1119 void mfc1(Register rt, FloatRegister fs) { emit_long(insn_COP1(mf_op, (int)rt->encoding(), (int)fs->encoding())); }
1120 void mov_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fmov_op)); }
1121 void mov_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fmov_op)); }
1122 void mtc1(Register rt, FloatRegister fs) { emit_long(insn_COP1(mt_op, (int)rt->encoding(), (int)fs->encoding())); }
1123 void mul_s(FloatRegister fd, FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), (int)fd->encoding(), fmul_op)); }
1124 void mul_d(FloatRegister fd, FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), (int)fd->encoding(), fmul_op)); }
1126 void neg_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fneg_op)); }
1127 void neg_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fneg_op)); }
1129 void round_l_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), froundl_op)); }
1130 void round_l_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), froundl_op)); }
1131 void round_w_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), froundw_op)); }
1132 void round_w_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), froundw_op)); }
1134 void sdc1(FloatRegister ft, Register base, int off) { emit_long(insn_ORRI(sdc1_op, (int)base->encoding(), (int)ft->encoding(), off)); }
1135 void sdc1(FloatRegister ft, Address dst);
1136 void sqrt_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fsqrt_op)); }
1137 void sqrt_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fsqrt_op)); }
1138 void sub_s(FloatRegister fd, FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(single_fmt, (int)ft->encoding(), (int)fs->encoding(), (int)fd->encoding(), fsub_op)); }
1139 void sub_d(FloatRegister fd, FloatRegister fs, FloatRegister ft) { emit_long(insn_F3RO(double_fmt, (int)ft->encoding(), (int)fs->encoding(), (int)fd->encoding(), fsub_op)); }
1140 void swc1(FloatRegister ft, Register base, int off) { emit_long(insn_ORRI(swc1_op, (int)base->encoding(), (int)ft->encoding(), off)); }
1141 void swc1(FloatRegister ft, Address dst);
1143 void trunc_l_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), ftruncl_op)); }
1144 void trunc_l_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), ftruncl_op)); }
1145 void trunc_w_s(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(single_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), ftruncw_op)); }
1146 void trunc_w_d(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(double_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), ftruncw_op)); }
1148 void int3();
1149 static void print_instruction(int);
1150 int patched_branch(int dest_pos, int inst, int inst_pos);
1151 int branch_destination(int inst, int pos);
1153 /* Godson3 extension */
1154 void gsldx(Register rt, Register base, Register index, int off) {
1155 assert(is_simm(off, 8), "gsldx: off exceeds 8 bits");
1156 emit_long(gsldx_op | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)index->encoding() << 11) | (off << 3));
1157 }
1159 void gslwx(Register rt, Register base, Register index, int off) {
1160 assert(is_simm(off, 8), "gslwx: off exceeds 8 bits");
1161 emit_long(gslwx_op | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)index->encoding() << 11) | (off << 3));
1162 }
1164 public:
1165 // Creation
1166 Assembler(CodeBuffer* code) : AbstractAssembler(code) {
1167 #ifdef CHECK_DELAY
1168 delay_state = no_delay;
1169 #endif
1170 }
1172 // Decoding
1173 static address locate_operand(address inst, WhichOperand which);
1174 static address locate_next_instruction(address inst);
1175 };
1178 // MacroAssembler extends Assembler by frequently used macros.
1179 //
1180 // Instructions for which a 'better' code sequence exists depending
1181 // on arguments should also go in here.
1183 class MacroAssembler: public Assembler {
1184 friend class LIR_Assembler;
1185 friend class Runtime1; // as_Address()
1187 public:
1188 static intptr_t i[32];
1189 static float f[32];
1190 static void print(outputStream *s);
1192 static int i_offset(unsigned int k);
1193 static int f_offset(unsigned int k);
1195 static void save_registers(MacroAssembler *masm);
1196 static void restore_registers(MacroAssembler *masm);
1198 protected:
1200 Address as_Address(AddressLiteral adr);
1201 Address as_Address(ArrayAddress adr);
1203 // Support for VM calls
1204 //
1205 // This is the base routine called by the different versions of call_VM_leaf. The interpreter
1206 // may customize this version by overriding it for its purposes (e.g., to save/restore
1207 // additional registers when doing a VM call).
1208 #ifdef CC_INTERP
1209 // c++ interpreter never wants to use interp_masm version of call_VM
1210 #define VIRTUAL
1211 #else
1212 #define VIRTUAL virtual
1213 #endif
1215 VIRTUAL void call_VM_leaf_base(
1216 address entry_point, // the entry point
1217 int number_of_arguments // the number of arguments to pop after the call
1218 );
1220 // This is the base routine called by the different versions of call_VM. The interpreter
1221 // may customize this version by overriding it for its purposes (e.g., to save/restore
1222 // additional registers when doing a VM call).
1223 //
1224 // If no java_thread register is specified (noreg) than rdi will be used instead. call_VM_base
1225 // returns the register which contains the thread upon return. If a thread register has been
1226 // specified, the return value will correspond to that register. If no last_java_sp is specified
1227 // (noreg) than rsp will be used instead.
1228 VIRTUAL void call_VM_base( // returns the register containing the thread upon return
1229 Register oop_result, // where an oop-result ends up if any; use noreg otherwise
1230 Register java_thread, // the thread if computed before ; use noreg otherwise
1231 Register last_java_sp, // to set up last_Java_frame in stubs; use noreg otherwise
1232 address entry_point, // the entry point
1233 int number_of_arguments, // the number of arguments (w/o thread) to pop after the call
1234 bool check_exceptions // whether to check for pending exceptions after return
1235 );
1237 // These routines should emit JVMTI PopFrame and ForceEarlyReturn handling code.
1238 // The implementation is only non-empty for the InterpreterMacroAssembler,
1239 // as only the interpreter handles PopFrame and ForceEarlyReturn requests.
1240 virtual void check_and_handle_popframe(Register java_thread);
1241 virtual void check_and_handle_earlyret(Register java_thread);
1243 void call_VM_helper(Register oop_result, address entry_point, int number_of_arguments, bool check_exceptions = true);
1245 // helpers for FPU flag access
1246 // tmp is a temporary register, if none is available use noreg
1247 //void save_rax (Register tmp);
1248 //void restore_rax(Register tmp);
1250 public:
1251 MacroAssembler(CodeBuffer* code) : Assembler(code) {}
1253 // Support for NULL-checks
1254 //
1255 // Generates code that causes a NULL OS exception if the content of reg is NULL.
1256 // If the accessed location is M[reg + offset] and the offset is known, provide the
1257 // offset. No explicit code generation is needed if the offset is within a certain
1258 // range (0 <= offset <= page_size).
1259 // use "teq 83, reg" in mips now, by yjl 6/20/2005
1260 void null_check(Register reg, int offset = -1);
1261 static bool needs_explicit_null_check(intptr_t offset);
1263 // Required platform-specific helpers for Label::patch_instructions.
1264 // They _shadow_ the declarations in AbstractAssembler, which are undefined.
1265 void pd_patch_instruction(address branch, address target);
1267 // Alignment
1268 void align(int modulus);
1270 // Misc
1271 //void fat_nop(); // 5 byte nop
1273 // Stack frame creation/removal
1274 void enter();
1275 void leave();
1277 // Support for getting the JavaThread pointer (i.e.; a reference to thread-local information)
1278 // The pointer will be loaded into the thread register.
1279 void get_thread(Register thread);
1282 // Support for VM calls
1283 //
1284 // It is imperative that all calls into the VM are handled via the call_VM macros.
1285 // They make sure that the stack linkage is setup correctly. call_VM's correspond
1286 // to ENTRY/ENTRY_X entry points while call_VM_leaf's correspond to LEAF entry points.
1289 void call_VM(Register oop_result,
1290 address entry_point,
1291 bool check_exceptions = true);
1292 void call_VM(Register oop_result,
1293 address entry_point,
1294 Register arg_1,
1295 bool check_exceptions = true);
1296 void call_VM(Register oop_result,
1297 address entry_point,
1298 Register arg_1, Register arg_2,
1299 bool check_exceptions = true);
1300 void call_VM(Register oop_result,
1301 address entry_point,
1302 Register arg_1, Register arg_2, Register arg_3,
1303 bool check_exceptions = true);
1304 // Super call_VM calls - correspond to MacroAssembler::call_VM(_leaf) calls
1305 void super_call_VM_leaf(address entry_point);
1306 void super_call_VM_leaf(address entry_point, Register arg_1);
1307 void super_call_VM_leaf(address entry_point, Register arg_1, Register arg_2);
1308 void super_call_VM_leaf(address entry_point,
1309 Register arg_1, Register arg_2, Register arg_3);
1311 // Overloadings with last_Java_sp
1312 void call_VM(Register oop_result,
1313 Register last_java_sp,
1314 address entry_point,
1315 int number_of_arguments = 0,
1316 bool check_exceptions = true);
1317 void call_VM(Register oop_result,
1318 Register last_java_sp,
1319 address entry_point,
1320 Register arg_1, bool
1321 check_exceptions = true);
1322 void call_VM(Register oop_result,
1323 Register last_java_sp,
1324 address entry_point,
1325 Register arg_1, Register arg_2,
1326 bool check_exceptions = true);
1327 void call_VM(Register oop_result,
1328 Register last_java_sp,
1329 address entry_point,
1330 Register arg_1, Register arg_2, Register arg_3,
1331 bool check_exceptions = true);
1333 void call_VM_leaf(address entry_point,
1334 int number_of_arguments = 0);
1335 void call_VM_leaf(address entry_point,
1336 Register arg_1);
1337 void call_VM_leaf(address entry_point,
1338 Register arg_1, Register arg_2);
1339 void call_VM_leaf(address entry_point,
1340 Register arg_1, Register arg_2, Register arg_3);
1342 // last Java Frame (fills frame anchor)
1343 void set_last_Java_frame(Register thread,
1344 Register last_java_sp,
1345 Register last_java_fp,
1346 address last_java_pc);
1348 // thread in the default location (r15_thread on 64bit)
1349 void set_last_Java_frame(Register last_java_sp,
1350 Register last_java_fp,
1351 address last_java_pc);
1353 void reset_last_Java_frame(Register thread, bool clear_fp, bool clear_pc);
1355 // thread in the default location (r15_thread on 64bit)
1356 void reset_last_Java_frame(bool clear_fp, bool clear_pc);
1358 // Stores
1359 void store_check(Register obj); // store check for obj - register is destroyed afterwards
1360 void store_check(Register obj, Address dst); // same as above, dst is exact store location (reg. is destroyed)
1363 void g1_write_barrier_pre(Register obj,
1364 #ifndef _LP64
1365 Register thread,
1366 #endif
1367 Register tmp,
1368 Register tmp2,
1369 bool tosca_live);
1370 void g1_write_barrier_post(Register store_addr,
1371 Register new_val,
1372 #ifndef _LP64
1373 Register thread,
1374 #endif
1375 Register tmp,
1376 Register tmp2);
1380 // split store_check(Register obj) to enhance instruction interleaving
1381 void store_check_part_1(Register obj);
1382 void store_check_part_2(Register obj);
1384 // C 'boolean' to Java boolean: x == 0 ? 0 : 1
1385 void c2bool(Register x);
1386 //add for compressedoops
1387 void load_klass(Register dst, Register src);
1388 void store_klass(Register dst, Register src);
1389 void load_prototype_header(Register dst, Register src);
1390 /*
1391 // C++ bool manipulation
1393 void movbool(Register dst, Address src);
1394 void movbool(Address dst, bool boolconst);
1395 void movbool(Address dst, Register src);
1396 void testbool(Register dst);
1398 // oop manipulations
1399 void load_klass(Register dst, Register src);
1400 void store_klass(Register dst, Register src);
1402 void load_prototype_header(Register dst, Register src);*/
1404 #ifdef _LP64
1405 void store_klass_gap(Register dst, Register src);
1407 void load_heap_oop(Register dst, Address src);
1408 void store_heap_oop(Address dst, Register src);
1409 void encode_heap_oop(Register r);
1410 void decode_heap_oop(Register r);
1411 void encode_heap_oop_not_null(Register r);
1412 void decode_heap_oop_not_null(Register r);
1413 void encode_heap_oop_not_null(Register dst, Register src);
1414 void decode_heap_oop_not_null(Register dst, Register src);
1416 void encode_klass_not_null(Register r);
1417 void decode_klass_not_null(Register r);
1418 void encode_klass_not_null(Register dst, Register src);
1419 void decode_klass_not_null(Register dst, Register src);
1421 //void set_narrow_oop(Register dst, jobject obj);
1423 // Returns the byte size of the instructions generated by decode_klass_not_null()
1424 // when compressed klass pointers are being used.
1425 static int instr_size_for_decode_klass_not_null();
1427 // if heap base register is used - reinit it with the correct value
1428 void reinit_heapbase();
1429 DEBUG_ONLY(void verify_heapbase(const char* msg);)
1431 #endif // _LP64
1433 void incrementl(Register reg, int value = 1);
1435 void decrementl(Register reg, int value = 1);
1437 /*
1438 // Int division/remainder for Java
1439 // (as idivl, but checks for special case as described in JVM spec.)
1440 // returns idivl instruction offset for implicit exception handling
1441 int corrected_idivl(Register reg);
1443 // Long division/remainder for Java
1444 // (as idivq, but checks for special case as described in JVM spec.)
1445 // returns idivq instruction offset for implicit exception handling
1446 int corrected_idivq(Register reg);
1447 */
1449 void int3();
1450 /*
1451 // Long operation macros for a 32bit cpu
1452 // Long negation for Java
1453 void lneg(Register hi, Register lo);
1455 // Long multiplication for Java
1456 // (destroys contents of eax, ebx, ecx and edx)
1457 void lmul(int x_rsp_offset, int y_rsp_offset); // rdx:rax = x * y
1459 // Long shifts for Java
1460 // (semantics as described in JVM spec.)
1461 void lshl(Register hi, Register lo); // hi:lo << (rcx & 0x3f)
1462 void lshr(Register hi, Register lo, bool sign_extension = false); // hi:lo >> (rcx & 0x3f)
1464 // Long compare for Java
1465 // (semantics as described in JVM spec.)
1466 void lcmp2int(Register x_hi, Register x_lo, Register y_hi, Register y_lo); // x_hi = lcmp(x, y)
1469 // misc
1470 */
1471 // Sign extension
1472 #ifdef _LP64
1473 void sign_extend_short(Register reg) { dsll32(reg, reg, 16); dsra32(reg, reg, 16); }
1474 void sign_extend_byte(Register reg) { dsll32(reg, reg, 24); dsra32(reg, reg, 24); }
1475 #else
1476 void sign_extend_short(Register reg) { sll(reg, reg, 16); sra(reg, reg, 16); }
1477 void sign_extend_byte(Register reg) { sll(reg, reg, 24); sra(reg, reg, 24); }
1478 #endif
1479 void rem_s(FloatRegister fd, FloatRegister fs, FloatRegister ft, FloatRegister tmp);
1480 void rem_d(FloatRegister fd, FloatRegister fs, FloatRegister ft, FloatRegister tmp);
1482 // Inlined sin/cos generator for Java; must not use CPU instruction
1483 // directly on Intel as it does not have high enough precision
1484 // outside of the range [-pi/4, pi/4]. Extra argument indicate the
1485 // number of FPU stack slots in use; all but the topmost will
1486 // require saving if a slow case is necessary. Assumes argument is
1487 // on FP TOS; result is on FP TOS. No cpu registers are changed by
1488 // this code.
1489 void trigfunc(char trig, int num_fpu_regs_in_use = 1);
1490 /*
1491 // branch to L if FPU flag C2 is set/not set
1492 // tmp is a temporary register, if none is available use noreg
1493 void jC2 (Register tmp, Label& L);
1494 void jnC2(Register tmp, Label& L);
1496 // Pop ST (ffree & fincstp combined)
1497 void fpop();
1499 // pushes double TOS element of FPU stack on CPU stack; pops from FPU stack
1500 void push_fTOS();
1502 // pops double TOS element from CPU stack and pushes on FPU stack
1503 void pop_fTOS();
1505 void empty_FPU_stack();
1507 void push_IU_state();
1508 void pop_IU_state();
1510 void push_FPU_state();
1511 void pop_FPU_state();
1513 void push_CPU_state();
1514 void pop_CPU_state();
1516 // Round up to a power of two
1517 void round_to(Register reg, int modulus);
1519 // Callee saved registers handling
1520 void push_callee_saved_registers();
1521 void pop_callee_saved_registers();
1522 */
1523 // allocation
1524 void eden_allocate(
1525 Register obj, // result: pointer to object after successful allocation
1526 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise
1527 int con_size_in_bytes, // object size in bytes if known at compile time
1528 Register t1, // temp register
1529 Register t2,
1530 Label& slow_case // continuation point if fast allocation fails
1531 );
1532 void tlab_allocate(
1533 Register obj, // result: pointer to object after successful allocation
1534 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise
1535 int con_size_in_bytes, // object size in bytes if known at compile time
1536 Register t1, // temp register
1537 Register t2, // temp register
1538 Label& slow_case // continuation point if fast allocation fails
1539 );
1540 void tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case);
1542 //----
1543 // void set_word_if_not_zero(Register reg); // sets reg to 1 if not zero, otherwise 0
1546 // Debugging
1548 // only if +VerifyOops
1549 void verify_oop(Register reg, const char* s = "broken oop");
1550 void verify_oop_addr(Address addr, const char * s = "broken oop addr");
1551 void verify_oop_subroutine();
1552 // TODO: verify method and klass metadata (compare against vptr?)
1553 void _verify_method_ptr(Register reg, const char * msg, const char * file, int line) {}
1554 void _verify_klass_ptr(Register reg, const char * msg, const char * file, int line){}
1556 #define verify_method_ptr(reg) _verify_method_ptr(reg, "broken method " #reg, __FILE__, __LINE__)
1557 #define verify_klass_ptr(reg) _verify_klass_ptr(reg, "broken klass " #reg, __FILE__, __LINE__)
1559 // only if +VerifyFPU
1560 void verify_FPU(int stack_depth, const char* s = "illegal FPU state");
1562 // prints msg, dumps registers and stops execution
1563 void stop(const char* msg);
1565 // prints msg and continues
1566 void warn(const char* msg);
1568 static void debug(char* msg/*, RegistersForDebugging* regs*/);
1569 static void debug32(int rdi, int rsi, int rbp, int rsp, int rbx, int rdx, int rcx, int rax, int eip, char* msg);
1570 static void debug64(char* msg, int64_t pc, int64_t regs[]);
1572 void print_reg(Register reg);
1573 void print_reg(FloatRegister reg);
1574 //void os_breakpoint();
1576 void untested() { stop("untested"); }
1578 void unimplemented(const char* what = "") { char* b = new char[1024]; jio_snprintf(b, sizeof(b), "unimplemented: %s", what); stop(b); }
1580 void should_not_reach_here() { stop("should not reach here"); }
1582 void print_CPU_state();
1584 // Stack overflow checking
1585 void bang_stack_with_offset(int offset) {
1586 // stack grows down, caller passes positive offset
1587 assert(offset > 0, "must bang with negative offset");
1588 if (offset <= 32768) {
1589 sw(A0, SP, -offset);
1590 } else {
1591 #ifdef _LP64
1592 li(AT, offset);
1593 dsub(AT, SP, AT);
1594 #else
1595 move(AT, offset);
1596 sub(AT, SP, AT);
1597 #endif
1598 sw(A0, AT, 0);
1599 }
1600 }
1602 // Writes to stack successive pages until offset reached to check for
1603 // stack overflow + shadow pages. Also, clobbers tmp
1604 void bang_stack_size(Register size, Register tmp);
1605 virtual RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr,
1606 Register tmp,
1607 int offset);
1609 // Support for serializing memory accesses between threads
1610 void serialize_memory(Register thread, Register tmp);
1612 //void verify_tlab();
1613 void verify_tlab(Register t1, Register t2);
1615 // Biased locking support
1616 // lock_reg and obj_reg must be loaded up with the appropriate values.
1617 // swap_reg must be rax, and is killed.
1618 // tmp_reg is optional. If it is supplied (i.e., != noreg) it will
1619 // be killed; if not supplied, push/pop will be used internally to
1620 // allocate a temporary (inefficient, avoid if possible).
1621 // Optional slow case is for implementations (interpreter and C1) which branch to
1622 // slow case directly. Leaves condition codes set for C2's Fast_Lock node.
1623 // Returns offset of first potentially-faulting instruction for null
1624 // check info (currently consumed only by C1). If
1625 // swap_reg_contains_mark is true then returns -1 as it is assumed
1626 // the calling code has already passed any potential faults.
1627 int biased_locking_enter(Register lock_reg, Register obj_reg,
1628 Register swap_reg, Register tmp_reg,
1629 bool swap_reg_contains_mark,
1630 Label& done, Label* slow_case = NULL,
1631 BiasedLockingCounters* counters = NULL);
1632 void biased_locking_exit (Register obj_reg, Register temp_reg, Label& done);
1635 // Calls
1637 void call(address entry);
1638 void call(address entry, relocInfo::relocType rtype);
1639 void call(address entry, RelocationHolder& rh);
1640 // Emit the CompiledIC call idiom
1641 void ic_call(address entry);
1643 void jmp(address entry);
1644 void jmp(address entry, relocInfo::relocType rtype);
1646 // Argument ops
1647 /*inline void store_int_argument(Register s, Argument& a);
1648 inline void store_long_argument(Register s, Argument& a);
1649 inline void store_float_argument(FloatRegister s, Argument& a);
1650 inline void store_double_argument(FloatRegister s, Argument& a);
1651 inline void store_ptr_argument(Register s, Argument& a);*/
1652 inline void store_int_argument(Register s, Argument &a) {
1653 if(a.is_Register()) {
1654 move(a.as_Register(), s);
1655 } else {
1656 sw(s, a.as_caller_address());
1657 }
1658 }
1660 inline void store_long_argument(Register s, Argument &a) {
1661 Argument a1 = a.successor();
1662 if(a.is_Register() && a1.is_Register()) {
1663 move(a.as_Register(), s);
1664 move(a.as_Register(), s);
1665 } else {
1666 sd(s, a.as_caller_address());
1667 }
1668 }
1670 inline void store_float_argument(FloatRegister s, Argument &a) {
1671 if(a.is_Register()) {
1672 mov_s(a.as_FloatRegister(), s);
1673 } else {
1674 swc1(s, a.as_caller_address());
1675 }
1676 }
1677 inline void store_double_argument(FloatRegister s, Argument &a) {
1678 if(a.is_Register()) {
1679 mov_d(a.as_FloatRegister(), s);
1680 } else {
1681 sdc1(s, a.as_caller_address());
1682 }
1683 }
1685 inline void store_ptr_argument(Register s, Argument &a) {
1686 if(a.is_Register()) {
1687 move(a.as_Register(), s);
1688 } else {
1689 st_ptr(s, a.as_caller_address());
1690 }
1691 }
1693 // Load and store values by size and signed-ness
1694 void load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed, Register dst2 = noreg);
1695 void store_sized_value(Address dst, Register src, size_t size_in_bytes, Register src2 = noreg);
1697 // interface method calling
1698 void lookup_interface_method(Register recv_klass,
1699 Register intf_klass,
1700 RegisterOrConstant itable_index,
1701 Register method_result,
1702 Register scan_temp,
1703 Label& no_such_interface);
1704 // virtual method calling
1705 void lookup_virtual_method(Register recv_klass,
1706 RegisterOrConstant vtable_index,
1707 Register method_result);
1709 // ld_ptr will perform lw for 32 bit VMs and ld for 64 bit VMs
1710 // st_ptr will perform sw for 32 bit VMs and sd for 64 bit VMs
1711 inline void ld_ptr(Register rt, Address a){
1712 #ifdef _LP64
1713 ld(rt, a.base(), a.disp());
1714 #else
1715 lw(rt, a.base(), a.disp());
1716 #endif
1717 }
1718 inline void ld_ptr(Register rt, Register base, int offset16){
1719 #ifdef _LP64
1720 ld(rt, base, offset16);
1721 #else
1722 lw(rt, base, offset16);
1723 #endif
1725 }
1726 inline void st_ptr(Register rt, Address a){
1727 #ifdef _LP64
1728 sd(rt, a.base(), a.disp());
1729 #else
1730 sw(rt, a.base(), a.disp());
1731 #endif
1732 }
1733 inline void st_ptr(Register rt, Register base, int offset16) {
1734 #ifdef _LP64
1735 sd(rt, base, offset16);
1736 #else
1737 sw(rt, base, offset16);
1738 #endif
1740 }
1742 void ld_ptr(Register rt, Register offset, Register base);
1743 void st_ptr(Register rt, Register offset, Register base);
1745 // ld_long will perform lw for 32 bit VMs and ld for 64 bit VMs
1746 // st_long will perform sw for 32 bit VMs and sd for 64 bit VMs
1747 inline void ld_long(Register rt, Register base, int offset16);
1748 inline void st_long(Register rt, Register base, int offset16);
1749 inline void ld_long(Register rt, Address a);
1750 inline void st_long(Register rt, Address a);
1753 void ld_long(Register rt, Register offset, Register base);
1754 void st_long(Register rt, Register offset, Register base);
1755 // Regular vs. d* versions
1756 inline void addu_long(Register rd, Register rs, Register rt) {
1757 #ifdef _LP64
1758 daddu(rd, rs, rt);
1759 #else
1760 addu(rd, rs, rt);
1761 #endif
1762 }
1763 inline void addu_long(Register rd, Register rs, long imm32_64) {
1764 #ifdef _LP64
1765 daddiu(rd, rs, imm32_64);
1766 #else
1767 addiu(rd, rs, imm32_64);
1768 #endif
1770 }
1772 // Floating
1773 public:
1774 // swap the two byte of the low 16-bit halfword
1775 // this directive will use AT, be sure the high 16-bit of reg is zero
1776 // by yjl 6/28/2005
1777 void hswap(Register reg);
1778 void huswap(Register reg);
1780 // convert big endian integer to little endian integer
1781 // by yjl 6/29/2005
1782 void swap(Register reg);
1784 // implement the x86 instruction semantic
1785 // if c_reg == *dest then *dest <= x_reg
1786 // else c_reg <= *dest
1787 // the AT indicate if xchg occurred, 1 for xchged, else 0
1788 // by yjl 6/28/2005
1789 void cmpxchg(Register x_reg, Address dest, Register c_reg);
1790 #ifdef _LP64
1791 void cmpxchg32(Register x_reg, Address dest, Register c_reg);
1792 #endif
1793 void cmpxchg8(Register x_regLo, Register x_regHi, Address dest, Register c_regLo, Register c_regHi);
1797 void round_to(Register reg, int modulus) {
1798 assert_different_registers(reg, AT);
1799 increment(reg, modulus - 1);
1800 move(AT, - modulus);
1801 andr(reg, reg, AT);
1802 }
1804 //pop & push, added by aoqi
1805 #ifdef _LP64
1806 void extend_sign(Register rh, Register rl) { stop("extend_sign"); }
1807 void neg(Register reg) { dsubu(reg, R0, reg); }
1808 void push (Register reg) { sd (reg, SP, -8); daddi(SP, SP, -8); }
1809 void push (FloatRegister reg) { sdc1(reg, SP, -8); daddi(SP, SP, -8); }
1810 void pop (Register reg) { ld (reg, SP, 0); daddi(SP, SP, 8); }
1811 void pop (FloatRegister reg) { ldc1(reg, SP, 0); daddi(SP, SP, 8); }
1812 void pop () { daddi(SP, SP, 8); }
1813 void pop2 () { daddi(SP, SP, 16); }
1814 #else
1815 void extend_sign(Register rh, Register rl) { sra(rh, rl, 31); }
1816 void neg(Register reg) { subu(reg, R0, reg); }
1817 void push (Register reg) { sw (reg, SP, -4); addi(SP, SP, -4); }
1818 void push (FloatRegister reg) { swc1(reg, SP, -4); addi(SP, SP, -4); }
1819 void pop (Register reg) { lw (reg, SP, 0); addi(SP, SP, 4); }
1820 void pop (FloatRegister reg) { lwc1(reg, SP, 0); addi(SP, SP, 4); }
1821 void pop () { addi(SP, SP, 4); }
1822 void pop2 () { addi(SP, SP, 8); }
1823 #endif
1824 void push2(Register reg1, Register reg2);
1825 void pop2 (Register reg1, Register reg2);
1826 void dpush (Register reg) { sd (reg, SP, -8); daddi(SP, SP, -8); }
1827 void dpop (Register reg) { ld (reg, SP, 0); daddi(SP, SP, 8); }
1829 /* branches may exceed 16-bit offset */
1830 void b_far(address entry);
1831 void b_far(Label& L);
1833 void bne_far (Register rs, Register rt, address entry);
1834 void bne_far (Register rs, Register rt, Label& L);
1836 void beq_far (Register rs, Register rt, address entry);
1837 void beq_far (Register rs, Register rt, Label& L);
1839 //move an 32-bit immediate to Register
1840 void move(Register reg, int imm32) { li32(reg, imm32); }
1841 void li (Register rd, long imm);
1842 void li (Register rd, address addr) { li(rd, (long)addr); }
1843 //replace move(Register reg, int imm)
1844 void li32(Register rd, int imm32); // sign-extends to 64 bits on mips64
1845 #ifdef _LP64
1846 void dli(Register rd, long imm) { li(rd, imm); }
1847 void li64(Register rd, long imm);
1848 void li48(Register rd, long imm);
1849 #endif
1851 #ifdef _LP64
1852 void move(Register rd, Register rs) { dadd(rd, rs, R0); }
1853 void move_u32(Register rd, Register rs) { addu32(rd, rs, R0); }
1854 #else
1855 void move(Register rd, Register rs) { add(rd, rs, R0); }
1856 #endif
1857 void dmove(Register rd, Register rs) { dadd(rd, rs, R0); }
1859 #ifdef _LP64
1860 void shl(Register reg, int sa) { dsll(reg, reg, sa); }
1861 void shr(Register reg, int sa) { dsrl(reg, reg, sa); }
1862 void sar(Register reg, int sa) { dsra(reg, reg, sa); }
1863 #else
1864 void shl(Register reg, int sa) { sll(reg, reg, sa); }
1865 void shr(Register reg, int sa) { srl(reg, reg, sa); }
1866 void sar(Register reg, int sa) { sra(reg, reg, sa); }
1867 #endif
1869 #ifndef PRODUCT
1870 static void pd_print_patched_instruction(address branch) {
1871 jint stub_inst = *(jint*) branch;
1872 print_instruction(stub_inst);
1873 ::tty->print("%s", " (unresolved)");
1875 }
1876 #endif
1878 // the follow two might use AT register, be sure you have no meanful data in AT before you call them
1879 // by yjl 6/23/2005
1880 void increment(Register reg, int imm);
1881 void decrement(Register reg, int imm);
1883 //FIXME
1884 void empty_FPU_stack(){/*need implemented*/};
1886 //we need 2 fun to save and resotre general register
1887 void pushad();
1888 void popad();
1890 // Test sub_klass against super_klass, with fast and slow paths.
1892 // The fast path produces a tri-state answer: yes / no / maybe-slow.
1893 // One of the three labels can be NULL, meaning take the fall-through.
1894 // If super_check_offset is -1, the value is loaded up from super_klass.
1895 // No registers are killed, except temp_reg.
1896 void check_klass_subtype_fast_path(Register sub_klass,
1897 Register super_klass,
1898 Register temp_reg,
1899 Label* L_success,
1900 Label* L_failure,
1901 Label* L_slow_path,
1902 RegisterOrConstant super_check_offset = RegisterOrConstant(-1));
1904 // The rest of the type check; must be wired to a corresponding fast path.
1905 // It does not repeat the fast path logic, so don't use it standalone.
1906 // The temp_reg and temp2_reg can be noreg, if no temps are available.
1907 // Updates the sub's secondary super cache as necessary.
1908 // If set_cond_codes, condition codes will be Z on success, NZ on failure.
1909 void check_klass_subtype_slow_path(Register sub_klass,
1910 Register super_klass,
1911 Register temp_reg,
1912 Register temp2_reg,
1913 Label* L_success,
1914 Label* L_failure,
1915 bool set_cond_codes = false);
1917 // Simplified, combined version, good for typical uses.
1918 // Falls through on failure.
1919 void check_klass_subtype(Register sub_klass,
1920 Register super_klass,
1921 Register temp_reg,
1922 Label& L_success);
1924 // method handles (JSR 292)
1925 Address argument_address(RegisterOrConstant arg_slot, int extra_slot_offset = 0);
1927 void get_vm_result (Register oop_result, Register thread);
1928 void get_vm_result_2(Register metadata_result, Register thread);
1929 #undef VIRTUAL
1930 void atomic_inc32(address counter_addr, int inc, Register tmp_reg1, Register tmp_reg2);
1932 void fast_lock(Register obj, Register box, Register tmp, Register scr);
1933 void fast_unlock(Register obj, Register box, Register tmp);
1934 };
1936 /**
1937 * class SkipIfEqual:
1938 *
1939 * Instantiating this class will result in assembly code being output that will
1940 * jump around any code emitted between the creation of the instance and it's
1941 * automatic destruction at the end of a scope block, depending on the value of
1942 * the flag passed to the constructor, which will be checked at run-time.
1943 */
1944 class SkipIfEqual {
1945 private:
1946 MacroAssembler* _masm;
1947 Label _label;
1949 public:
1950 SkipIfEqual(MacroAssembler*, const bool* flag_addr, bool value);
1951 ~SkipIfEqual();
1952 };
1954 #ifdef ASSERT
1955 inline bool AbstractAssembler::pd_check_instruction_mark() { return true; }
1956 #endif
1958 #endif // CPU_MIPS_VM_ASSEMBLER_MIPS_HPP