Sat, 18 Feb 2017 18:25:01 -0500
[Assembler] Add right-rotate instructions for MIPS.
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 // opcode, highest 6 bits: bits[31...26]
369 enum ops {
370 special_op = 0x00, // special_ops
371 regimm_op = 0x01, // regimm_ops
372 j_op = 0x02,
373 jal_op = 0x03,
374 beq_op = 0x04,
375 bne_op = 0x05,
376 blez_op = 0x06,
377 bgtz_op = 0x07,
378 addi_op = 0x08,
379 addiu_op = 0x09,
380 slti_op = 0x0a,
381 sltiu_op = 0x0b,
382 andi_op = 0x0c,
383 ori_op = 0x0d,
384 xori_op = 0x0e,
385 lui_op = 0x0f,
386 cop0_op = 0x10, // cop0_ops
387 cop1_op = 0x11, // cop1_ops
388 gs_cop2_op = 0x12, // gs_cop2_ops
389 cop1x_op = 0x13, // cop1x_ops
390 beql_op = 0x14,
391 bnel_op = 0x15,
392 blezl_op = 0x16,
393 bgtzl_op = 0x17,
394 daddi_op = 0x18,
395 daddiu_op = 0x19,
396 ldl_op = 0x1a,
397 ldr_op = 0x1b,
398 special2_op = 0x1c, // special2_ops
399 msa_op = 0x1e, // msa_ops
400 special3_op = 0x1f, // special3_ops
401 lb_op = 0x20,
402 lh_op = 0x21,
403 lwl_op = 0x22,
404 lw_op = 0x23,
405 lbu_op = 0x24,
406 lhu_op = 0x25,
407 lwr_op = 0x26,
408 lwu_op = 0x27,
409 sb_op = 0x28,
410 sh_op = 0x29,
411 swl_op = 0x2a,
412 sw_op = 0x2b,
413 sdl_op = 0x2c,
414 sdr_op = 0x2d,
415 swr_op = 0x2e,
416 cache_op = 0x2f,
417 ll_op = 0x30,
418 lwc1_op = 0x31,
419 gs_lwc2_op = 0x32, //gs_lwc2_ops
420 pref_op = 0x33,
421 lld_op = 0x34,
422 ldc1_op = 0x35,
423 gs_ldc2_op = 0x36, //gs_ldc2_ops
424 ld_op = 0x37,
425 sc_op = 0x38,
426 swc1_op = 0x39,
427 gs_swc2_op = 0x3a, //gs_swc2_ops
428 scd_op = 0x3c,
429 sdc1_op = 0x3d,
430 gs_sdc2_op = 0x3e, //gs_sdc2_ops
431 sd_op = 0x3f
432 };
434 static const char *ops_name[];
436 //special family, the opcode is in low 6 bits.
437 enum special_ops {
438 sll_op = 0x00,
439 movci_op = 0x01,
440 srl_op = 0x02,
441 sra_op = 0x03,
442 sllv_op = 0x04,
443 srlv_op = 0x06,
444 srav_op = 0x07,
445 jr_op = 0x08,
446 jalr_op = 0x09,
447 movz_op = 0x0a,
448 movn_op = 0x0b,
449 syscall_op = 0x0c,
450 break_op = 0x0d,
451 sync_op = 0x0f,
452 mfhi_op = 0x10,
453 mthi_op = 0x11,
454 mflo_op = 0x12,
455 mtlo_op = 0x13,
456 dsllv_op = 0x14,
457 dsrlv_op = 0x16,
458 dsrav_op = 0x17,
459 mult_op = 0x18,
460 multu_op = 0x19,
461 div_op = 0x1a,
462 divu_op = 0x1b,
463 dmult_op = 0x1c,
464 dmultu_op = 0x1d,
465 ddiv_op = 0x1e,
466 ddivu_op = 0x1f,
467 add_op = 0x20,
468 addu_op = 0x21,
469 sub_op = 0x22,
470 subu_op = 0x23,
471 and_op = 0x24,
472 or_op = 0x25,
473 xor_op = 0x26,
474 nor_op = 0x27,
475 slt_op = 0x2a,
476 sltu_op = 0x2b,
477 dadd_op = 0x2c,
478 daddu_op = 0x2d,
479 dsub_op = 0x2e,
480 dsubu_op = 0x2f,
481 tge_op = 0x30,
482 tgeu_op = 0x31,
483 tlt_op = 0x32,
484 tltu_op = 0x33,
485 teq_op = 0x34,
486 tne_op = 0x36,
487 dsll_op = 0x38,
488 dsrl_op = 0x3a,
489 dsra_op = 0x3b,
490 dsll32_op = 0x3c,
491 dsrl32_op = 0x3e,
492 dsra32_op = 0x3f
493 };
495 static const char* special_name[];
497 //regimm family, the opcode is in rt[16...20], 5 bits
498 enum regimm_ops {
499 bltz_op = 0x00,
500 bgez_op = 0x01,
501 bltzl_op = 0x02,
502 bgezl_op = 0x03,
503 tgei_op = 0x08,
504 tgeiu_op = 0x09,
505 tlti_op = 0x0a,
506 tltiu_op = 0x0b,
507 teqi_op = 0x0c,
508 tnei_op = 0x0e,
509 bltzal_op = 0x10,
510 bgezal_op = 0x11,
511 bltzall_op = 0x12,
512 bgezall_op = 0x13,
513 bposge32_op = 0x1c,
514 bposge64_op = 0x1d,
515 synci_op = 0x1f,
516 };
518 static const char* regimm_name[];
520 //cop0 family, the ops is in bits[25...21], 5 bits
521 enum cop0_ops {
522 mfc0_op = 0x00,
523 dmfc0_op = 0x01,
524 //
525 mxgc0_op = 0x03, //MFGC0, DMFGC0, MTGC0
526 mtc0_op = 0x04,
527 dmtc0_op = 0x05,
528 rdpgpr_op = 0x0a,
529 inter_op = 0x0b,
530 wrpgpr_op = 0x0c
531 };
533 //cop1 family, the ops is in bits[25...21], 5 bits
534 enum cop1_ops {
535 mfc1_op = 0x00,
536 dmfc1_op = 0x01,
537 cfc1_op = 0x02,
538 mfhc1_op = 0x03,
539 mtc1_op = 0x04,
540 dmtc1_op = 0x05,
541 ctc1_op = 0x06,
542 mthc1_op = 0x07,
543 bc1f_op = 0x08,
544 single_fmt = 0x10,
545 double_fmt = 0x11,
546 word_fmt = 0x14,
547 long_fmt = 0x15,
548 ps_fmt = 0x16
549 };
552 //2 bist (bits[17...16]) of bc1x instructions (cop1)
553 enum bc_ops {
554 bcf_op = 0x0,
555 bct_op = 0x1,
556 bcfl_op = 0x2,
557 bctl_op = 0x3,
558 };
560 // low 6 bits of c_x_fmt instructions (cop1)
561 enum c_conds {
562 f_cond = 0x30,
563 un_cond = 0x31,
564 eq_cond = 0x32,
565 ueq_cond = 0x33,
566 olt_cond = 0x34,
567 ult_cond = 0x35,
568 ole_cond = 0x36,
569 ule_cond = 0x37,
570 sf_cond = 0x38,
571 ngle_cond = 0x39,
572 seq_cond = 0x3a,
573 ngl_cond = 0x3b,
574 lt_cond = 0x3c,
575 nge_cond = 0x3d,
576 le_cond = 0x3e,
577 ngt_cond = 0x3f
578 };
580 // low 6 bits of cop1 instructions
581 enum float_ops {
582 fadd_op = 0x00,
583 fsub_op = 0x01,
584 fmul_op = 0x02,
585 fdiv_op = 0x03,
586 fsqrt_op = 0x04,
587 fabs_op = 0x05,
588 fmov_op = 0x06,
589 fneg_op = 0x07,
590 froundl_op = 0x08,
591 ftruncl_op = 0x09,
592 fceill_op = 0x0a,
593 ffloorl_op = 0x0b,
594 froundw_op = 0x0c,
595 ftruncw_op = 0x0d,
596 fceilw_op = 0x0e,
597 ffloorw_op = 0x0f,
598 movf_f_op = 0x11,
599 movt_f_op = 0x11,
600 movz_f_op = 0x12,
601 movn_f_op = 0x13,
602 frecip_op = 0x15,
603 frsqrt_op = 0x16,
604 fcvts_op = 0x20,
605 fcvtd_op = 0x21,
606 fcvtw_op = 0x24,
607 fcvtl_op = 0x25,
608 fcvtps_op = 0x26,
609 fcvtspl_op = 0x28,
610 fpll_op = 0x2c,
611 fplu_op = 0x2d,
612 fpul_op = 0x2e,
613 fpuu_op = 0x2f
614 };
616 static const char* cop1_name[];
618 //cop1x family, the opcode is in low 6 bits.
619 enum cop1x_ops {
620 lwxc1_op = 0x00,
621 ldxc1_op = 0x01,
622 luxc1_op = 0x05,
623 swxc1_op = 0x08,
624 sdxc1_op = 0x09,
625 suxc1_op = 0x0d,
626 prefx_op = 0x0f,
628 alnv_ps_op = 0x1e,
629 madd_s_op = 0x20,
630 madd_d_op = 0x21,
631 madd_ps_op = 0x26,
632 msub_s_op = 0x28,
633 msub_d_op = 0x29,
634 msub_ps_op = 0x2e,
635 nmadd_s_op = 0x30,
636 nmadd_d_op = 0x31,
637 nmadd_ps_op = 0x36,
638 nmsub_s_op = 0x38,
639 nmsub_d_op = 0x39,
640 nmsub_ps_op = 0x3e
641 };
643 static const char* cop1x_name[];
645 //special2 family, the opcode is in low 6 bits.
646 enum special2_ops {
647 madd_op = 0x00,
648 maddu_op = 0x01,
649 mul_op = 0x02,
650 gs0x03_op = 0x03,
651 msub_op = 0x04,
652 msubu_op = 0x05,
653 gs0x06_op = 0x06,
654 gsemul2_op = 0x07,
655 gsemul3_op = 0x08,
656 gsemul4_op = 0x09,
657 gsemul5_op = 0x0a,
658 gsemul6_op = 0x0b,
659 gsemul7_op = 0x0c,
660 gsemul8_op = 0x0d,
661 gsemul9_op = 0x0e,
662 gsemul10_op = 0x0f,
663 gsmult_op = 0x10,
664 gsdmult_op = 0x11,
665 gsmultu_op = 0x12,
666 gsdmultu_op = 0x13,
667 gsdiv_op = 0x14,
668 gsddiv_op = 0x15,
669 gsdivu_op = 0x16,
670 gsddivu_op = 0x17,
671 gsmod_op = 0x1c,
672 gsdmod_op = 0x1d,
673 gsmodu_op = 0x1e,
674 gsdmodu_op = 0x1f,
675 clz_op = 0x20,
676 clo_op = 0x21,
677 xctx_op = 0x22, //ctz, cto, dctz, dcto, gsX
678 gsrxr_x_op = 0x23, //gsX
679 dclz_op = 0x24,
680 dclo_op = 0x25,
681 gsle_op = 0x26,
682 gsgt_op = 0x27,
683 gs86j_op = 0x28,
684 gsloop_op = 0x29,
685 gsaj_op = 0x2a,
686 gsldpc_op = 0x2b,
687 gs86set_op = 0x30,
688 gstm_op = 0x31,
689 gscvt_ld_op = 0x32,
690 gscvt_ud_op = 0x33,
691 gseflag_op = 0x34,
692 gscam_op = 0x35,
693 gstop_op = 0x36,
694 gssettag_op = 0x37,
695 gssdbbp_op = 0x38
696 };
698 static const char* special2_name[];
700 // special3 family, the opcode is in low 6 bits.
701 enum special3_ops {
702 ext_op = 0x00,
703 dextm_op = 0x01,
704 dextu_op = 0x02,
705 dext_op = 0x03,
706 ins_op = 0x04,
707 dinsm_op = 0x05,
708 dinsu_op = 0x06,
709 dins_op = 0x07,
710 lxx_op = 0x0a, //lwx, lhx, lbux, ldx
711 insv_op = 0x0c,
712 dinsv_op = 0x0d,
713 ar1_op = 0x10, //MIPS DSP
714 cmp1_op = 0x11, //MIPS DSP
715 re1_op = 0x12, //MIPS DSP, re1_ops
716 sh1_op = 0x13, //MIPS DSP
717 ar2_op = 0x14, //MIPS DSP
718 cmp2_op = 0x15, //MIPS DSP
719 re2_op = 0x16, //MIPS DSP, re2_ops
720 sh2_op = 0x17, //MIPS DSP
721 ar3_op = 0x18, //MIPS DSP
722 bshfl_op = 0x20 //seb, seh
723 };
725 // re1_ops
726 enum re1_ops {
727 absq_s_qb_op = 0x01,
728 repl_qb_op = 0x02,
729 replv_qb_op = 0x03,
730 absq_s_ph_op = 0x09,
731 repl_ph_op = 0x0a,
732 replv_ph_op = 0x0b,
733 absq_s_w_op = 0x11,
734 bitrev_op = 0x1b
735 };
737 // re2_ops
738 enum re2_ops {
739 repl_ob_op = 0x02,
740 replv_ob_op = 0x03,
741 absq_s_qh_op = 0x09,
742 repl_qh_op = 0x0a,
743 replv_qh_op = 0x0b,
744 absq_s_pw_op = 0x11,
745 repl_pw_op = 0x12,
746 replv_pw_op = 0x13,
747 };
749 static const char* special3_name[];
751 // lwc2/gs_lwc2 family, the opcode is in low 6 bits.
752 enum gs_lwc2_ops {
753 gslq_op = 0x20
754 };
756 static const char* gs_lwc2_name[];
758 // ldc2/gs_ldc2 family, the opcode is in low 3 bits.
759 enum gs_ldc2_ops {
760 gslbx_op = 0x0,
761 gslhx_op = 0x1,
762 gslwx_op = 0x2,
763 gsldx_op = 0x3,
764 gslwxc1_op = 0x6,
765 gsldxc1_op = 0x7
766 };
768 static const char* gs_ldc2_name[];
770 // swc2/gs_swc2 family, the opcode is in low 6 bits.
771 enum gs_swc2_ops {
772 gssq_op = 0x20
773 };
775 static const char* gs_swc2_name[];
777 // sdc2/gs_sdc2 family, the opcode is in low 3 bits.
778 enum gs_sdc2_ops {
779 gssbx_op = 0x0,
780 gsshx_op = 0x1,
781 gsswx_op = 0x2,
782 gssdx_op = 0x3,
783 gsswxc1_op = 0x6,
784 gssdxc1_op = 0x7
785 };
787 static const char* gs_sdc2_name[];
789 /* 2013.10.16 Jin: merge from OpenJDK 8 */
790 enum WhichOperand {
791 // input to locate_operand, and format code for relocations
792 imm_operand = 0, // embedded 32-bit|64-bit immediate operand
793 disp32_operand = 1, // embedded 32-bit displacement or address
794 call32_operand = 2, // embedded 32-bit self-relative displacement
795 #ifndef _LP64
796 _WhichOperand_limit = 3
797 #else
798 narrow_oop_operand = 3, // embedded 32-bit immediate narrow oop
799 _WhichOperand_limit = 4
800 #endif
801 };
803 static int opcode(int insn) { return (insn>>26)&0x3f; }
804 static int rs(int insn) { return (insn>>21)&0x1f; }
805 static int rt(int insn) { return (insn>>16)&0x1f; }
806 static int rd(int insn) { return (insn>>11)&0x1f; }
807 static int sa(int insn) { return (insn>>6)&0x1f; }
808 static int special(int insn) { return insn&0x3f; }
809 static int imm_off(int insn) { return (short)low16(insn); }
811 static int low (int x, int l) { return bitfield(x, 0, l); }
812 static int low16(int x) { return low(x, 16); }
813 static int low26(int x) { return low(x, 26); }
815 protected:
816 //help methods for instruction ejection
818 // I-Type (Immediate)
819 // 31 26 25 21 20 16 15 0
820 //| opcode | rs | rt | immediat |
821 //| | | | |
822 // 6 5 5 16
823 static int insn_ORRI(int op, int rs, int rt, int imm) { return (op<<26) | (rs<<21) | (rt<<16) | low16(imm); }
825 // R-Type (Register)
826 // 31 26 25 21 20 16 15 11 10 6 5 0
827 //| special | rs | rt | rd | 0 | opcode |
828 //| 0 0 0 0 0 0 | | | | 0 0 0 0 0 | |
829 // 6 5 5 5 5 6
830 static int insn_RRRO(int rs, int rt, int rd, int op) { return (rs<<21) | (rt<<16) | (rd<<11) | op; }
831 static int insn_RRSO(int rt, int rd, int sa, int op) { return (rt<<16) | (rd<<11) | (sa<<6) | op; }
832 static int insn_RRCO(int rs, int rt, int code, int op) { return (rs<<21) | (rt<<16) | (code<<6) | op; }
834 static int insn_COP0(int op, int rt, int rd) { return (cop0_op<<26) | (op<<21) | (rt<<16) | (rd<<11); }
835 static int insn_COP1(int op, int rt, int fs) { return (cop1_op<<26) | (op<<21) | (rt<<16) | (fs<<11); }
837 static int insn_F3RO(int fmt, int ft, int fs, int fd, int func) {
838 return (cop1_op<<26) | (fmt<<21) | (ft<<16) | (fs<<11) | (fd<<6) | func;
839 }
840 static int insn_F3ROX(int fmt, int ft, int fs, int fd, int func) {
841 return (cop1x_op<<26) | (fmt<<21) | (ft<<16) | (fs<<11) | (fd<<6) | func;
842 }
845 //static int low (int x, int l) { return bitfield(x, 0, l); }
846 //static int low16(int x) { return low(x, 16); }
847 //static int low26(int x) { return low(x, 26); }
849 static int high (int x, int l) { return bitfield(x, 32-l, l); }
850 static int high16(int x) { return high(x, 16); }
851 static int high6 (int x) { return high(x, 6); }
853 //get the offset field of jump/branch instruction
854 int offset(address entry) {
855 assert(is_simm16((entry - pc() - 4) / 4), "change this code");
856 if (!is_simm16((entry - pc() - 4) / 4)) {
857 tty->print_cr("!!! is_simm16: %x", (entry - pc() - 4) / 4);
858 }
859 return (entry - pc() - 4) / 4;
860 }
863 public:
864 using AbstractAssembler::offset;
866 //sign expand with the sign bit is h
867 static int expand(int x, int h) { return -(x & (1<<h)) | x; }
869 // If x is a mask, return the number of one-bit in x.
870 // else return -1.
871 static int is_int_mask(int x);
873 // If x is a mask, return the number of one-bit in x.
874 // else return -1.
875 static int is_jlong_mask(jlong x);
877 // MIPS lui/addiu is both sign extended, so if you wan't to use off32/imm32, you have to use the follow three
878 static int split_low(int x) {
879 return (x & 0xffff);
880 }
882 static int split_high(int x) {
883 return ( (x >> 16) + ((x & 0x8000) != 0) ) & 0xffff;
884 }
886 static int merge(int low, int high) {
887 return expand(low, 15) + (high<<16);
888 }
890 #ifdef _LP64
891 static intptr_t merge(intptr_t x0, intptr_t x16, intptr_t x32, intptr_t x48) {
892 return (x48 << 48) | (x32 << 32) | (x16 << 16) | x0;
893 }
894 #endif
896 // modified by spark 2005/08/18
897 static bool is_simm (int x, int nbits) { return -( 1 << nbits-1 ) <= x && x < ( 1 << nbits-1 ); }
898 static bool is_simm16(int x) { return is_simm(x, 16); }
900 static bool fit_in_jal(int offset) {
901 return is_simm(offset, 26);
902 }
905 // test if entry can be filled in the jl/jal,
906 // must be used just before you emit jl/jal
907 // by yjl 6/27/2005
908 bool fit_int_jal(address entry) {
909 return fit_in_jal(offset(entry));
910 }
912 bool fit_int_branch(address entry) {
913 return is_simm16(offset(entry));
914 }
916 protected:
917 #ifdef ASSERT
918 #define CHECK_DELAY
919 #endif
920 #ifdef CHECK_DELAY
921 enum Delay_state { no_delay, at_delay_slot, filling_delay_slot } delay_state;
922 #endif
924 public:
925 void assert_not_delayed() {
926 #ifdef CHECK_DELAY
927 assert_not_delayed("next instruction should not be a delay slot");
928 #endif
929 }
931 void assert_not_delayed(const char* msg) {
932 #ifdef CHECK_DELAY
933 //guarantee( delay_state == no_delay, msg );
934 //aoqi_test
935 if(delay_state != no_delay){
936 tty->print_cr("%s:%d, pc: %lx", __func__, __LINE__, pc());
937 }
938 assert(delay_state == no_delay, msg);
939 #endif
940 }
942 protected:
943 // Delay slot helpers
944 // cti is called when emitting control-transfer instruction,
945 // BEFORE doing the emitting.
946 // Only effective when assertion-checking is enabled.
948 // called when emitting cti with a delay slot, AFTER emitting
949 void has_delay_slot() {
950 #ifdef CHECK_DELAY
951 assert_not_delayed("just checking");
952 delay_state = at_delay_slot;
953 #endif
954 }
956 public:
957 Assembler* delayed() {
958 #ifdef CHECK_DELAY
959 guarantee( delay_state == at_delay_slot, "delayed instructition is not in delay slot");
960 delay_state = filling_delay_slot;
961 #endif
962 return this;
963 }
965 void flush() {
966 #ifdef CHECK_DELAY
967 guarantee( delay_state == no_delay, "ending code with a delay slot");
968 #endif
969 AbstractAssembler::flush();
970 }
972 inline void emit_long(int); // shadows AbstractAssembler::emit_long
973 inline void emit_data(int x) { emit_long(x); }
974 inline void emit_data(int, RelocationHolder const&);
975 inline void emit_data(int, relocInfo::relocType rtype);
976 inline void check_delay();
979 // Generic instructions
980 // Does 32bit or 64bit as needed for the platform. In some sense these
981 // belong in macro assembler but there is no need for both varieties to exist
983 #ifndef _LP64
984 void add(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), add_op)); }
985 void addi(Register rt, Register rs, int imm) { emit_long(insn_ORRI(addi_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
986 void addiu(Register rt, Register rs, int imm) { emit_long(insn_ORRI(addiu_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
987 void addu(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), addu_op)); }
988 #else
989 void add(Register rd, Register rs, Register rt) { dadd (rd, rs, rt); }
990 void add32(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), add_op)); }
991 void addu32(Register rd, Register rs, Register rt){ emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), addu_op)); }
992 void addiu32(Register rt, Register rs, int imm) { emit_long(insn_ORRI(addiu_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
993 void addi(Register rt, Register rs, int imm) { daddi (rt, rs, imm);}
994 void addiu(Register rt, Register rs, int imm) { daddiu (rt, rs, imm);}
995 void addu(Register rd, Register rs, Register rt) { daddu (rd, rs, rt); }
996 #endif
998 void andr(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), and_op)); }
999 void andi(Register rt, Register rs, int imm) { emit_long(insn_ORRI(andi_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
1001 void beq (Register rs, Register rt, int off) { emit_long(insn_ORRI(beq_op, (int)rs->encoding(), (int)rt->encoding(), off)); has_delay_slot(); }
1002 void beql (Register rs, Register rt, int off) { emit_long(insn_ORRI(beql_op, (int)rs->encoding(), (int)rt->encoding(), off)); has_delay_slot(); }
1003 void bgez (Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bgez_op, off)); has_delay_slot(); }
1004 void bgezal (Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bgezal_op, off)); has_delay_slot(); }
1005 void bgezall(Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bgezall_op, off)); has_delay_slot(); }
1006 void bgezl (Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bgezl_op, off)); has_delay_slot(); }
1007 void bgtz (Register rs, int off) { emit_long(insn_ORRI(bgtz_op, (int)rs->encoding(), 0, off)); has_delay_slot(); }
1008 void bgtzl (Register rs, int off) { emit_long(insn_ORRI(bgtzl_op, (int)rs->encoding(), 0, off)); has_delay_slot(); }
1009 void blez (Register rs, int off) { emit_long(insn_ORRI(blez_op, (int)rs->encoding(), 0, off)); has_delay_slot(); }
1010 void blezl (Register rs, int off) { emit_long(insn_ORRI(blezl_op, (int)rs->encoding(), 0, off)); has_delay_slot(); }
1011 void bltz (Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bltz_op, off)); has_delay_slot(); }
1012 void bltzal (Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bltzal_op, off)); has_delay_slot(); }
1013 void bltzall(Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bltzall_op, off)); has_delay_slot(); }
1014 void bltzl (Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bltzl_op, off)); has_delay_slot(); }
1015 void bne (Register rs, Register rt, int off) { emit_long(insn_ORRI(bne_op, (int)rs->encoding(), (int)rt->encoding(), off)); has_delay_slot(); }
1016 void bnel (Register rs, Register rt, int off) { emit_long(insn_ORRI(bnel_op, (int)rs->encoding(), (int)rt->encoding(), off)); has_delay_slot(); }
1017 void brk (int code) { emit_long(break_op | (code<<16)); }
1019 void beq (Register rs, Register rt, address entry) { beq(rs, rt, offset(entry)); }
1020 void beql (Register rs, Register rt, address entry) { beql(rs, rt, offset(entry));}
1021 void bgez (Register rs, address entry) { bgez (rs, offset(entry)); }
1022 void bgezal (Register rs, address entry) { bgezal (rs, offset(entry)); }
1023 void bgezall(Register rs, address entry) { bgezall(rs, offset(entry)); }
1024 void bgezl (Register rs, address entry) { bgezl (rs, offset(entry)); }
1025 void bgtz (Register rs, address entry) { bgtz (rs, offset(entry)); }
1026 void bgtzl (Register rs, address entry) { bgtzl (rs, offset(entry)); }
1027 void blez (Register rs, address entry) { blez (rs, offset(entry)); }
1028 void blezl (Register rs, address entry) { blezl (rs, offset(entry)); }
1029 void bltz (Register rs, address entry) { bltz (rs, offset(entry)); }
1030 void bltzal (Register rs, address entry) { bltzal (rs, offset(entry)); }
1031 void bltzall(Register rs, address entry) { bltzall(rs, offset(entry)); }
1032 void bltzl (Register rs, address entry) { bltzl (rs, offset(entry)); }
1033 void bne (Register rs, Register rt, address entry) { bne(rs, rt, offset(entry)); }
1034 void bnel (Register rs, Register rt, address entry) { bnel(rs, rt, offset(entry)); }
1036 void beq (Register rs, Register rt, Label& L) { beq(rs, rt, target(L)); }
1037 void beql (Register rs, Register rt, Label& L) { beql(rs, rt, target(L)); }
1038 void bgez (Register rs, Label& L){ bgez (rs, target(L)); }
1039 void bgezal (Register rs, Label& L){ bgezal (rs, target(L)); }
1040 void bgezall(Register rs, Label& L){ bgezall(rs, target(L)); }
1041 void bgezl (Register rs, Label& L){ bgezl (rs, target(L)); }
1042 void bgtz (Register rs, Label& L){ bgtz (rs, target(L)); }
1043 void bgtzl (Register rs, Label& L){ bgtzl (rs, target(L)); }
1044 void blez (Register rs, Label& L){ blez (rs, target(L)); }
1045 void blezl (Register rs, Label& L){ blezl (rs, target(L)); }
1046 void bltz (Register rs, Label& L){ bltz (rs, target(L)); }
1047 void bltzal (Register rs, Label& L){ bltzal (rs, target(L)); }
1048 void bltzall(Register rs, Label& L){ bltzall(rs, target(L)); }
1049 void bltzl (Register rs, Label& L){ bltzl (rs, target(L)); }
1050 void bne (Register rs, Register rt, Label& L){ bne(rs, rt, target(L)); }
1051 void bnel (Register rs, Register rt, Label& L){ bnel(rs, rt, target(L)); }
1053 void dadd (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), dadd_op)); }
1054 void daddi (Register rt, Register rs, int imm) { emit_long(insn_ORRI(daddi_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
1055 void daddiu(Register rt, Register rs, int imm) { emit_long(insn_ORRI(daddiu_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
1056 void daddu (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), daddu_op)); }
1057 void ddiv (Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, ddiv_op)); }
1058 void ddivu (Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, ddivu_op)); }
1060 void movz (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), movz_op)); }
1061 void movn (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), movn_op)); }
1063 void movt (Register rd, Register rs) { emit_long(((int)rs->encoding() << 21) | (1 << 16) | ((int)rd->encoding() << 11) | movci_op); }
1064 void movf (Register rd, Register rs) { emit_long(((int)rs->encoding() << 21) | ((int)rd->encoding() << 11) | movci_op); }
1066 enum bshfl_ops {
1067 seb_op = 0x10,
1068 seh_op = 0x18
1069 };
1070 void seb (Register rd, Register rt) { emit_long((special3_op << 26) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | (seb_op << 6) | bshfl_op); }
1071 void seh (Register rd, Register rt) { emit_long((special3_op << 26) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | (seh_op << 6) | bshfl_op); }
1073 void ext (Register rt, Register rs, int pos, int size) {
1074 guarantee((0 <= pos) && (pos < 32), "pos must be in [0, 32)");
1075 guarantee((0 < size) && (size <= 32), "size must be in (0, 32]");
1076 guarantee((0 < pos + size) && (pos + size <= 32), "pos + size must be in (0, 32]");
1078 int lsb = pos;
1079 int msbd = size - 1;
1081 emit_long((special3_op << 26) | ((int)rs->encoding() << 21) | ((int)rt->encoding() << 16) | (msbd << 11) | (lsb << 6) | ext_op);
1082 }
1084 void dext (Register rt, Register rs, int pos, int size) {
1085 guarantee((0 <= pos) && (pos < 32), "pos must be in [0, 32)");
1086 guarantee((0 < size) && (size <= 32), "size must be in (0, 32]");
1087 guarantee((0 < pos + size) && (pos + size <= 63), "pos + size must be in (0, 63]");
1089 int lsb = pos;
1090 int msbd = size - 1;
1092 emit_long((special3_op << 26) | ((int)rs->encoding() << 21) | ((int)rt->encoding() << 16) | (msbd << 11) | (lsb << 6) | dext_op);
1093 }
1095 void rotr (Register rd, Register rt, int sa) {
1096 emit_long((special_op << 26) | (1 << 21) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | (low(sa, 5) << 6) | srl_op);
1097 }
1099 void drotr (Register rd, Register rt, int sa) {
1100 emit_long((special_op << 26) | (1 << 21) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | (low(sa, 5) << 6) | dsrl_op);
1101 }
1103 void drotr32 (Register rd, Register rt, int sa) {
1104 emit_long((special_op << 26) | (1 << 21) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | (low(sa, 5) << 6) | dsrl32_op);
1105 }
1107 void rotrv (Register rd, Register rt, Register rs) {
1108 emit_long((special_op << 26) | ((int)rs->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | (1 << 6) | srlv_op);
1109 }
1111 void drotrv (Register rd, Register rt, Register rs) {
1112 emit_long((special_op << 26) | ((int)rs->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | (1 << 6) | dsrlv_op);
1113 }
1115 // Do mult and div need both 32-bit and 64-bit version? FIXME aoqi
1116 //#ifndef _LP64
1117 #if 1
1118 void div (Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, div_op)); }
1119 void divu (Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, divu_op)); }
1120 #else
1121 void div (Register rs, Register rt) { ddiv (rs, rt);}
1122 void divu (Register rs, Register rt) { ddivu(rs, rt);}
1123 #endif
1124 void dmult (Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, dmult_op)); }
1125 void dmultu(Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, dmultu_op)); }
1126 void dsll (Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), sa, dsll_op)); }
1127 void dsllv (Register rd, Register rt, Register rs) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), dsllv_op)); }
1128 void dsll32(Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), sa, dsll32_op)); }
1129 void dsra (Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), sa, dsra_op)); }
1130 void dsrav (Register rd, Register rt, Register rs) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), dsrav_op)); }
1131 void dsra32(Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), sa, dsra32_op)); }
1132 void dsrl (Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), sa, dsrl_op)); }
1133 void dsrlv (Register rd, Register rt, Register rs) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), dsrlv_op)); }
1134 void dsrl32(Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), sa, dsrl32_op)); }
1135 void dsub (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), dsub_op)); }
1136 void dsubu (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), dsubu_op)); }
1138 void b(int off) { beq(R0, R0, off); }
1139 void b(address entry) { b(offset(entry)); }
1140 void b(Label& L) { b(target(L)); }
1142 void j(address entry);
1143 void jal(address entry);
1145 void jalr(Register rd, Register rs) { emit_long( ((int)rs->encoding()<<21) | ((int)rd->encoding()<<11) | jalr_op); has_delay_slot(); }
1146 void jalr(Register rs) { jalr(RA, rs); }
1147 void jalr() { jalr(T9); }
1149 void jr(Register rs) { emit_long(((int)rs->encoding()<<21) | jr_op); has_delay_slot(); }
1151 void lb (Register rt, Register base, int off) { emit_long(insn_ORRI(lb_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1152 void lbu(Register rt, Register base, int off) { emit_long(insn_ORRI(lbu_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1153 void ld (Register rt, Register base, int off) { emit_long(insn_ORRI(ld_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1154 void ldl(Register rt, Register base, int off) { emit_long(insn_ORRI(ldl_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1155 void ldr(Register rt, Register base, int off) { emit_long(insn_ORRI(ldr_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1156 void lh (Register rt, Register base, int off) { emit_long(insn_ORRI(lh_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1157 void lhu(Register rt, Register base, int off) { emit_long(insn_ORRI(lhu_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1158 void ll (Register rt, Register base, int off) { emit_long(insn_ORRI(ll_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1159 void lld(Register rt, Register base, int off) { emit_long(insn_ORRI(lld_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1160 void lui(Register rt, int imm) { emit_long(insn_ORRI(lui_op, 0, (int)rt->encoding(), imm)); }
1161 void lw (Register rt, Register base, int off) { emit_long(insn_ORRI(lw_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1162 void lwl(Register rt, Register base, int off) { emit_long(insn_ORRI(lwl_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1163 void lwr(Register rt, Register base, int off) { emit_long(insn_ORRI(lwr_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1164 void lwu(Register rt, Register base, int off) { emit_long(insn_ORRI(lwu_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1166 void lb (Register rt, Address src);
1167 void lbu(Register rt, Address src);
1168 void ld (Register rt, Address src);
1169 void ldl(Register rt, Address src);
1170 void ldr(Register rt, Address src);
1171 void lh (Register rt, Address src);
1172 void lhu(Register rt, Address src);
1173 void ll (Register rt, Address src);
1174 void lld(Register rt, Address src);
1175 void lw (Register rt, Address src);
1176 void lwl(Register rt, Address src);
1177 void lwr(Register rt, Address src);
1178 void lwu(Register rt, Address src);
1179 void lea(Register rt, Address src);
1180 void pref(int hint, Register base, int off) { emit_long(insn_ORRI(pref_op, (int)base->encoding(), low(hint, 5), low(off, 16))); }
1182 void mfhi (Register rd) { emit_long( ((int)rd->encoding()<<11) | mfhi_op ); }
1183 void mflo (Register rd) { emit_long( ((int)rd->encoding()<<11) | mflo_op ); }
1184 void mthi (Register rs) { emit_long( ((int)rs->encoding()<<21) | mthi_op ); }
1185 void mtlo (Register rs) { emit_long( ((int)rs->encoding()<<21) | mtlo_op ); }
1186 // Do mult and div need both 32-bit and 64-bit version? FIXME aoqi
1187 //#ifndef _LP64
1188 #if 1
1189 void mult (Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, mult_op)); }
1190 void multu(Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, multu_op)); }
1191 #else
1192 void mult (Register rs, Register rt) { dmult (rs, rt); }
1193 void multu(Register rs, Register rt) { dmultu (rs, rt); }
1194 #endif
1196 void nor(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), nor_op)); }
1198 void orr(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), or_op)); }
1199 void ori(Register rt, Register rs, int imm) { emit_long(insn_ORRI(ori_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
1201 void sb (Register rt, Register base, int off) { emit_long(insn_ORRI(sb_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1202 void sc (Register rt, Register base, int off) { emit_long(insn_ORRI(sc_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1203 void scd (Register rt, Register base, int off) { emit_long(insn_ORRI(scd_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1204 void sd (Register rt, Register base, int off) { emit_long(insn_ORRI(sd_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1205 void sdl (Register rt, Register base, int off) { emit_long(insn_ORRI(sdl_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1206 void sdr (Register rt, Register base, int off) { emit_long(insn_ORRI(sdr_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1207 void sh (Register rt, Register base, int off) { emit_long(insn_ORRI(sh_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1208 //#ifndef _LP64
1209 #if 1
1210 void sll (Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), sa, sll_op)); }
1211 void sllv (Register rd, Register rt, Register rs) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), sllv_op)); }
1212 #else
1213 void sll (Register rd, Register rt , int sa) { dsll (rd, rt, sa);}
1214 void sllv (Register rd, Register rt, Register rs) { dsllv (rd, rt, rs); }
1215 #endif
1216 void slt (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), slt_op)); }
1217 void slti (Register rt, Register rs, int imm) { emit_long(insn_ORRI(slti_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
1218 void sltiu(Register rt, Register rs, int imm) { emit_long(insn_ORRI(sltiu_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
1219 void sltu (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), sltu_op)); }
1220 //#ifndef _LP64
1221 #if 1
1222 void sra (Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), sa, sra_op)); }
1223 void srav (Register rd, Register rt, Register rs) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), srav_op)); }
1224 void srl (Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), sa, srl_op)); }
1225 void srlv (Register rd, Register rt, Register rs) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), srlv_op)); }
1226 #else
1227 void sra (Register rd, Register rt , int sa) { dsra (rd, rt, sa); }
1228 void srav (Register rd, Register rt, Register rs) { dsrav (rd, rt, rs); }
1229 void srl (Register rd, Register rt , int sa) { dsrl (rd, rt, sa); }
1230 void srlv (Register rd, Register rt, Register rs) { dsrlv (rd, rt, rs); }
1231 #endif
1232 #ifndef _LP64
1233 void sub (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), sub_op)); }
1234 void subu (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), subu_op)); }
1235 #else
1236 void sub (Register rd, Register rs, Register rt) { dsub (rd, rs, rt); }
1237 void subu (Register rd, Register rs, Register rt) { dsubu (rd, rs, rt); }
1238 void subu32 (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), subu_op)); }
1239 #endif
1240 void sw (Register rt, Register base, int off) { emit_long(insn_ORRI(sw_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1241 void swl (Register rt, Register base, int off) { emit_long(insn_ORRI(swl_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1242 void swr (Register rt, Register base, int off) { emit_long(insn_ORRI(swr_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1243 void sync () { emit_long(sync_op); }
1244 void syscall(int code) { emit_long( (code<<6) | syscall_op ); }
1246 void sb(Register rt, Address dst);
1247 void sc(Register rt, Address dst);
1248 void scd(Register rt, Address dst);
1249 void sd(Register rt, Address dst);
1250 void sdl(Register rt, Address dst);
1251 void sdr(Register rt, Address dst);
1252 void sh(Register rt, Address dst);
1253 void sw(Register rt, Address dst);
1254 void swl(Register rt, Address dst);
1255 void swr(Register rt, Address dst);
1257 void teq (Register rs, Register rt, int code) { emit_long(insn_RRCO((int)rs->encoding(), (int)rt->encoding(), code, teq_op)); }
1258 void teqi (Register rs, int imm) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), teqi_op, imm)); }
1259 void tge (Register rs, Register rt, int code) { emit_long(insn_RRCO((int)rs->encoding(), (int)rt->encoding(), code, tge_op)); }
1260 void tgei (Register rs, int imm) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), tgei_op, imm)); }
1261 void tgeiu(Register rs, int imm) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), tgeiu_op, imm)); }
1262 void tgeu (Register rs, Register rt, int code) { emit_long(insn_RRCO((int)rs->encoding(), (int)rt->encoding(), code, tgeu_op)); }
1263 void tlt (Register rs, Register rt, int code) { emit_long(insn_RRCO((int)rs->encoding(), (int)rt->encoding(), code, tlt_op)); }
1264 void tlti (Register rs, int imm) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), tlti_op, imm)); }
1265 void tltiu(Register rs, int imm) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), tltiu_op, imm)); }
1266 void tltu (Register rs, Register rt, int code) { emit_long(insn_RRCO((int)rs->encoding(), (int)rt->encoding(), code, tltu_op)); }
1267 void tne (Register rs, Register rt, int code) { emit_long(insn_RRCO((int)rs->encoding(), (int)rt->encoding(), code, tne_op)); }
1268 void tnei (Register rs, int imm) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), tnei_op, imm)); }
1270 void xorr(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), xor_op)); }
1271 void xori(Register rt, Register rs, int imm) { emit_long(insn_ORRI(xori_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
1273 void nop() { emit_long(0); }
1277 void ldc1(FloatRegister ft, Register base, int off) { emit_long(insn_ORRI(ldc1_op, (int)base->encoding(), (int)ft->encoding(), off)); }
1278 void lwc1(FloatRegister ft, Register base, int off) { emit_long(insn_ORRI(lwc1_op, (int)base->encoding(), (int)ft->encoding(), off)); }
1279 void ldc1(FloatRegister ft, Address src);
1280 void lwc1(FloatRegister ft, Address src);
1282 //COP0
1283 void mfc0 (Register rt, Register rd) { emit_long(insn_COP0( mfc0_op, (int)rt->encoding(), (int)rd->encoding())); }
1284 void dmfc0 (Register rt, FloatRegister rd) { emit_long(insn_COP0(dmfc0_op, (int)rt->encoding(), (int)rd->encoding())); }
1285 // MFGC0, DMFGC0, MTGC0, DMTGC0 not implemented yet
1286 void mtc0 (Register rt, Register rd) { emit_long(insn_COP0( mtc0_op, (int)rt->encoding(), (int)rd->encoding())); }
1287 void dmtc0 (Register rt, FloatRegister rd) { emit_long(insn_COP0(dmtc0_op, (int)rt->encoding(), (int)rd->encoding())); }
1288 //COP0 end
1291 //COP1
1292 void mfc1 (Register rt, FloatRegister fs) { emit_long(insn_COP1 (mfc1_op, (int)rt->encoding(), (int)fs->encoding())); }
1293 void dmfc1(Register rt, FloatRegister fs) { emit_long(insn_COP1(dmfc1_op, (int)rt->encoding(), (int)fs->encoding())); }
1294 void cfc1 (Register rt, int fs) { emit_long(insn_COP1( cfc1_op, (int)rt->encoding(), fs)); }
1295 void mfhc1(Register rt, int fs) { emit_long(insn_COP1(mfhc1_op, (int)rt->encoding(), fs)); }
1296 void mtc1 (Register rt, FloatRegister fs) { emit_long(insn_COP1( mtc1_op, (int)rt->encoding(), (int)fs->encoding())); }
1297 void dmtc1(Register rt, FloatRegister fs) { emit_long(insn_COP1(dmtc1_op, (int)rt->encoding(), (int)fs->encoding())); }
1298 void ctc1 (Register rt, FloatRegister fs) { emit_long(insn_COP1( ctc1_op, (int)rt->encoding(), (int)fs->encoding())); }
1299 void ctc1 (Register rt, int fs) { emit_long(insn_COP1(ctc1_op, (int)rt->encoding(), fs)); }
1300 void mthc1(Register rt, int fs) { emit_long(insn_COP1(mthc1_op, (int)rt->encoding(), fs)); }
1302 void bc1f (int off) { emit_long(insn_ORRI(cop1_op, bc1f_op, bcf_op, off)); has_delay_slot(); }
1303 void bc1fl(int off) { emit_long(insn_ORRI(cop1_op, bc1f_op, bcfl_op, off)); has_delay_slot(); }
1304 void bc1t (int off) { emit_long(insn_ORRI(cop1_op, bc1f_op, bct_op, off)); has_delay_slot(); }
1305 void bc1tl(int off) { emit_long(insn_ORRI(cop1_op, bc1f_op, bctl_op, off)); has_delay_slot(); }
1307 void bc1f (address entry) { bc1f(offset(entry)); }
1308 void bc1fl(address entry) { bc1fl(offset(entry)); }
1309 void bc1t (address entry) { bc1t(offset(entry)); }
1310 void bc1tl(address entry) { bc1tl(offset(entry)); }
1312 void bc1f (Label& L) { bc1f(target(L)); }
1313 void bc1fl(Label& L) { bc1fl(target(L)); }
1314 void bc1t (Label& L) { bc1t(target(L)); }
1315 void bc1tl(Label& L) { bc1tl(target(L)); }
1317 //R0->encoding() is 0; INSN_SINGLE is enclosed by {} for ctags.
1318 #define INSN_SINGLE(r1, r2, r3, op) \
1319 { emit_long(insn_F3RO(single_fmt, (int)r1->encoding(), (int)r2->encoding(), (int)r3->encoding(), op));}
1320 void add_s (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, fd, fadd_op)}
1321 void sub_s (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, fd, fsub_op)}
1322 void mul_s (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, fd, fmul_op)}
1323 void div_s (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, fd, fdiv_op)}
1324 void sqrt_s (FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, fsqrt_op)}
1325 void abs_s (FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, fabs_op)}
1326 void mov_s (FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, fmov_op)}
1327 void neg_s (FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, fneg_op)}
1328 void round_l_s(FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, froundl_op)}
1329 void trunc_l_s(FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, ftruncl_op)}
1330 void ceil_l_s (FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, fceill_op)}
1331 void floor_l_s(FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, ffloorl_op)}
1332 void round_w_s(FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, froundw_op)}
1333 void trunc_w_s(FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, ftruncw_op)}
1334 void ceil_w_s (FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, fceilw_op)}
1335 void floor_w_s(FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, ffloorw_op)}
1336 //null
1337 //void movf_s(FloatRegister rd, FloatRegister rs, FPConditionCode cc) { unimplemented(" movf_s")}
1338 //void movt_s(FloatRegister rd, FloatRegister rs, FPConditionCode cc) { unimplemented(" movt_s") }
1339 void movz_s (FloatRegister fd, FloatRegister fs, Register rt) {INSN_SINGLE(rt, fs, fd, movz_f_op)}
1340 void movn_s (FloatRegister fd, FloatRegister fs, Register rt) {INSN_SINGLE(rt, fs, fd, movn_f_op)}
1341 //null
1342 void recip_s (FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, frecip_op)}
1343 void rsqrt_s (FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, frsqrt_op)}
1344 //null
1345 void cvt_d_s (FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, fcvtd_op)}
1346 //null
1347 void cvt_w_s (FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, fcvtw_op)}
1348 void cvt_l_s (FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, fcvtl_op)}
1349 void cvt_ps_s(FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, fd, fcvtps_op)}
1350 //null
1351 void c_f_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, f_cond)}
1352 void c_un_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, un_cond)}
1353 void c_eq_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, eq_cond)}
1354 void c_ueq_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, ueq_cond)}
1355 void c_olt_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, olt_cond)}
1356 void c_ult_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, ult_cond)}
1357 void c_ole_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, ole_cond)}
1358 void c_ule_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, ule_cond)}
1359 void c_sf_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, sf_cond)}
1360 void c_ngle_s(FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, ngle_cond)}
1361 void c_seq_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, seq_cond)}
1362 void c_ngl_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, ngl_cond)}
1363 void c_lt_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, lt_cond)}
1364 void c_nge_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, nge_cond)}
1365 void c_le_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, le_cond)}
1366 void c_ngt_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, ngt_cond)}
1368 #undef INSN_SINGLE
1371 //R0->encoding() is 0; INSN_DOUBLE is enclosed by {} for ctags.
1372 #define INSN_DOUBLE(r1, r2, r3, op) \
1373 { emit_long(insn_F3RO(double_fmt, (int)r1->encoding(), (int)r2->encoding(), (int)r3->encoding(), op));}
1375 void add_d (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, fd, fadd_op)}
1376 void sub_d (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, fd, fsub_op)}
1377 void mul_d (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, fd, fmul_op)}
1378 void div_d (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, fd, fdiv_op)}
1379 void sqrt_d (FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, fsqrt_op)}
1380 void abs_d (FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, fabs_op)}
1381 void mov_d (FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, fmov_op)}
1382 void neg_d (FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, fneg_op)}
1383 void round_l_d(FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, froundl_op)}
1384 void trunc_l_d(FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, ftruncl_op)}
1385 void ceil_l_d (FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, fceill_op)}
1386 void floor_l_d(FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, ffloorl_op)}
1387 void round_w_d(FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, froundw_op)}
1388 void trunc_w_d(FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, ftruncw_op)}
1389 void ceil_w_d (FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, fceilw_op)}
1390 void floor_w_d(FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, ffloorw_op)}
1391 //null
1392 //void movf_d(Register rd, Register rs, FPConditionCode cc) { unimplemented(" movf_d")}
1393 //void movt_d(Register rd, Register rs, FPConditionCode cc) { unimplemented(" movt_d") }
1394 void movz_d (FloatRegister fd, FloatRegister fs, Register rt) {INSN_DOUBLE(rt, fs, fd, movz_f_op)}
1395 void movn_d (FloatRegister fd, FloatRegister fs, Register rt) {INSN_DOUBLE(rt, fs, fd, movn_f_op)}
1396 //null
1397 void recip_d (FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, frecip_op)}
1398 void rsqrt_d (FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, frsqrt_op)}
1399 //null
1400 void cvt_s_d (FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, fcvts_op)}
1401 void cvt_l_d (FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, fcvtl_op)}
1402 //null
1403 void cvt_w_d (FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, fcvtw_op)}
1404 //null
1405 void c_f_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, f_cond)}
1406 void c_un_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, un_cond)}
1407 void c_eq_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, eq_cond)}
1408 void c_ueq_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, ueq_cond)}
1409 void c_olt_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, olt_cond)}
1410 void c_ult_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, ult_cond)}
1411 void c_ole_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, ole_cond)}
1412 void c_ule_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, ule_cond)}
1413 void c_sf_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, sf_cond)}
1414 void c_ngle_d(FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, ngle_cond)}
1415 void c_seq_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, seq_cond)}
1416 void c_ngl_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, ngl_cond)}
1417 void c_lt_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, lt_cond)}
1418 void c_nge_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, nge_cond)}
1419 void c_le_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, le_cond)}
1420 void c_ngt_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, ngt_cond)}
1422 #undef INSN_DOUBLE
1425 //null
1426 void cvt_s_w(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(word_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvts_op)); }
1427 void cvt_d_w(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(word_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvtd_op)); }
1428 //null
1429 void cvt_s_l(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(long_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvts_op)); }
1430 void cvt_d_l(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(long_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvtd_op)); }
1431 //null
1434 //R0->encoding() is 0; INSN_PS is enclosed by {} for ctags.
1435 #define INSN_PS(r1, r2, r3, op) \
1436 { emit_long(insn_F3RO(ps_fmt, (int)r1->encoding(), (int)r2->encoding(), (int)r3->encoding(), op));}
1438 void add_ps (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, fd, fadd_op)}
1439 void sub_ps (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, fd, fsub_op)}
1440 void mul_ps (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, fd, fmul_op)}
1441 //null
1442 void abs_ps (FloatRegister fd, FloatRegister fs) {INSN_PS(R0, fs, fd, fabs_op)}
1443 void mov_ps (FloatRegister fd, FloatRegister fs) {INSN_PS(R0, fs, fd, fmov_op)}
1444 void neg_ps (FloatRegister fd, FloatRegister fs) {INSN_PS(R0, fs, fd, fneg_op)}
1445 //null
1446 //void movf_ps(FloatRegister rd, FloatRegister rs, FPConditionCode cc) { unimplemented(" movf_ps")}
1447 //void movt_ps(FloatRegister rd, FloatRegister rs, FPConditionCode cc) { unimplemented(" movt_ps") }
1448 void movz_ps (FloatRegister fd, FloatRegister fs, Register rt) {INSN_PS(rt, fs, fd, movz_f_op)}
1449 void movn_ps (FloatRegister fd, FloatRegister fs, Register rt) {INSN_PS(rt, fs, fd, movn_f_op)}
1450 //null
1451 void cvt_s_pu (FloatRegister fd, FloatRegister fs) {INSN_PS(R0, fs, fd, fcvts_op)}
1452 //null
1453 void cvt_s_pl (FloatRegister fd, FloatRegister fs) {INSN_PS(R0, fs, fd, fcvtspl_op)}
1454 //null
1455 void pll_ps (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, fd, fpll_op)}
1456 void plu_ps (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, fd, fplu_op)}
1457 void pul_ps (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, fd, fpul_op)}
1458 void puu_ps (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, fd, fpuu_op)}
1459 void c_f_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, f_cond)}
1460 void c_un_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, un_cond)}
1461 void c_eq_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, eq_cond)}
1462 void c_ueq_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, ueq_cond)}
1463 void c_olt_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, olt_cond)}
1464 void c_ult_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, ult_cond)}
1465 void c_ole_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, ole_cond)}
1466 void c_ule_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, ule_cond)}
1467 void c_sf_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, sf_cond)}
1468 void c_ngle_ps(FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, ngle_cond)}
1469 void c_seq_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, seq_cond)}
1470 void c_ngl_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, ngl_cond)}
1471 void c_lt_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, lt_cond)}
1472 void c_nge_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, nge_cond)}
1473 void c_le_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, le_cond)}
1474 void c_ngt_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, ngt_cond)}
1475 //null
1476 #undef INSN_PS
1477 //COP1 end
1480 //COP1X
1481 //R0->encoding() is 0; INSN_SINGLE is enclosed by {} for ctags.
1482 #define INSN_COP1X(r0, r1, r2, r3, op) \
1483 { emit_long(insn_F3ROX((int)r0->encoding(), (int)r1->encoding(), (int)r2->encoding(), (int)r3->encoding(), op));}
1484 void madd_s(FloatRegister fd, FloatRegister fr, FloatRegister fs, FloatRegister ft) {INSN_COP1X(fr, ft, fs, fd, madd_s_op) }
1485 void madd_d(FloatRegister fd, FloatRegister fr, FloatRegister fs, FloatRegister ft) {INSN_COP1X(fr, ft, fs, fd, madd_d_op) }
1486 void madd_ps(FloatRegister fd, FloatRegister fr, FloatRegister fs, FloatRegister ft){INSN_COP1X(fr, ft, fs, fd, madd_ps_op) }
1487 void msub_s(FloatRegister fd, FloatRegister fr, FloatRegister fs, FloatRegister ft) {INSN_COP1X(fr, ft, fs, fd, msub_s_op) }
1488 void msub_d(FloatRegister fd, FloatRegister fr, FloatRegister fs, FloatRegister ft) {INSN_COP1X(fr, ft, fs, fd, msub_d_op) }
1489 void msub_ps(FloatRegister fd, FloatRegister fr, FloatRegister fs, FloatRegister ft){INSN_COP1X(fr, ft, fs, fd, msub_ps_op) }
1490 void nmadd_s(FloatRegister fd, FloatRegister fr, FloatRegister fs, FloatRegister ft) {INSN_COP1X(fr, ft, fs, fd, nmadd_s_op) }
1491 void nmadd_d(FloatRegister fd, FloatRegister fr, FloatRegister fs, FloatRegister ft) {INSN_COP1X(fr, ft, fs, fd, nmadd_d_op) }
1492 void nmadd_ps(FloatRegister fd, FloatRegister fr, FloatRegister fs, FloatRegister ft){INSN_COP1X(fr, ft, fs, fd, nmadd_ps_op) }
1493 void nmsub_s(FloatRegister fd, FloatRegister fr, FloatRegister fs, FloatRegister ft) {INSN_COP1X(fr, ft, fs, fd, nmsub_s_op) }
1494 void nmsub_d(FloatRegister fd, FloatRegister fr, FloatRegister fs, FloatRegister ft) {INSN_COP1X(fr, ft, fs, fd, nmsub_d_op) }
1495 void nmsub_ps(FloatRegister fd, FloatRegister fr, FloatRegister fs, FloatRegister ft){INSN_COP1X(fr, ft, fs, fd, nmsub_ps_op) }
1496 #undef INSN_COP1X
1497 //COP1X end
1499 //SPECIAL2
1500 //R0->encoding() is 0; INSN_PS is enclosed by {} for ctags.
1501 #define INSN_S2(op) \
1502 { emit_long((special2_op << 26) | ((int)rs->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | op);}
1504 void madd (Register rs, Register rt) { emit_long((special2_op << 26) | ((int)rs->encoding() << 21) | ((int)rt->encoding() << 16) | madd_op); }
1505 void maddu(Register rs, Register rt) { emit_long((special2_op << 26) | ((int)rs->encoding() << 21) | ((int)rt->encoding() << 16) | maddu_op); }
1506 void mul (Register rd, Register rs, Register rt) { INSN_S2(mul_op) }
1507 void msub (Register rs, Register rt) { emit_long((special2_op << 26) | ((int)rs->encoding() << 21) | ((int)rt->encoding() << 16) | msub_op); }
1508 void msubu(Register rs, Register rt) { emit_long((special2_op << 26) | ((int)rs->encoding() << 21) | ((int)rt->encoding() << 16) | msubu_op); }
1510 void gsmult (Register rd, Register rs, Register rt) { INSN_S2(gsmult_op) }
1511 void gsdmult (Register rd, Register rs, Register rt) { INSN_S2(gsdmult_op) }
1512 void gsmultu (Register rd, Register rs, Register rt) { INSN_S2(gsmultu_op) }
1513 void gsdmultu(Register rd, Register rs, Register rt) { INSN_S2(gsdmultu_op)}
1514 void gsdiv (Register rd, Register rs, Register rt) { INSN_S2(gsdiv_op) }
1515 void gsddiv (Register rd, Register rs, Register rt) { INSN_S2(gsddiv_op) }
1516 void gsdivu (Register rd, Register rs, Register rt) { INSN_S2(gsdivu_op) }
1517 void gsddivu (Register rd, Register rs, Register rt) { INSN_S2(gsddivu_op) }
1518 void gsmod (Register rd, Register rs, Register rt) { INSN_S2(gsmod_op) }
1519 void gsdmod (Register rd, Register rs, Register rt) { INSN_S2(gsdmod_op) }
1520 void gsmodu (Register rd, Register rs, Register rt) { INSN_S2(gsmodu_op) }
1521 void gsdmodu (Register rd, Register rs, Register rt) { INSN_S2(gsdmodu_op) }
1522 void clz (Register rd, Register rs) { emit_long((special2_op << 26) | ((int)rs->encoding() << 21) | ((int)rd->encoding() << 16) | ((int)rd->encoding() << 11) | clz_op); }
1523 void clo (Register rd, Register rs) { emit_long((special2_op << 26) | ((int)rs->encoding() << 21) | ((int)rd->encoding() << 16) | ((int)rd->encoding() << 11) | clo_op); }
1524 void ctz (Register rd, Register rs) { emit_long((special2_op << 26) | ((int)rs->encoding() << 21) | ((int)rd->encoding() << 16) | ((int)rd->encoding() << 11) | 0 << 6| xctx_op); }
1525 void cto (Register rd, Register rs) { emit_long((special2_op << 26) | ((int)rs->encoding() << 21) | ((int)rd->encoding() << 16) | ((int)rd->encoding() << 11) | 1 << 6| xctx_op); }
1526 void dctz(Register rd, Register rs) { emit_long((special2_op << 26) | ((int)rs->encoding() << 21) | ((int)rd->encoding() << 16) | ((int)rd->encoding() << 11) | 2 << 6| xctx_op); }
1527 void dcto(Register rd, Register rs) { emit_long((special2_op << 26) | ((int)rs->encoding() << 21) | ((int)rd->encoding() << 16) | ((int)rd->encoding() << 11) | 3 << 6| xctx_op); }
1528 void dclz(Register rd, Register rs) { emit_long((special2_op << 26) | ((int)rs->encoding() << 21) | ((int)rd->encoding() << 16) | ((int)rd->encoding() << 11) | dclz_op); }
1529 void dclo(Register rd, Register rs) { emit_long((special2_op << 26) | ((int)rs->encoding() << 21) | ((int)rd->encoding() << 16) | ((int)rd->encoding() << 11) | dclo_op); }
1531 #undef INSN_S2
1533 //SPECIAL3
1534 /*
1535 // FIXME
1536 #define is_0_to_32(a, b) \
1537 assert (a >= 0, " just a check"); \
1538 assert (a <= 0, " just a check"); \
1539 assert (b >= 0, " just a check"); \
1540 assert (b <= 0, " just a check"); \
1541 assert (a+b >= 0, " just a check"); \
1542 assert (a+b <= 0, " just a check");
1543 */
1544 #define is_0_to_32(a, b)
1546 void ins (Register rt, Register rs, int pos, int size) { is_0_to_32(pos, size); emit_long((special3_op << 26) | ((int)rs->encoding() << 21) | ((int)rt->encoding() << 16) | (low(pos+size-1, 5) << 11) | (low(pos, 5) << 6) | ins_op); }
1547 void dinsm(Register rt, Register rs, int pos, int size) { is_0_to_32(pos, size); emit_long((special3_op << 26) | ((int)rs->encoding() << 21) | ((int)rt->encoding() << 16) | (low(pos+size-33, 5) << 11) | (low(pos, 5) << 6) | dinsm_op); }
1548 void dinsu(Register rt, Register rs, int pos, int size) { is_0_to_32(pos, size); emit_long((special3_op << 26) | ((int)rs->encoding() << 21) | ((int)rt->encoding() << 16) | (low(pos+size-33, 5) << 11) | (low(pos-32, 5) << 6) | dinsu_op); }
1549 void dins (Register rt, Register rs, int pos, int size) {
1550 guarantee((0 <= pos) && (pos < 32), "pos must be in [0, 32)");
1551 guarantee((0 < size) && (size <= 32), "size must be in (0, 32]");
1552 guarantee((0 < pos + size) && (pos + size <= 32), "pos + size must be in (0, 32]");
1554 emit_long((special3_op << 26) | ((int)rs->encoding() << 21) | ((int)rt->encoding() << 16) | (low(pos+size-1, 5) << 11) | (low(pos, 5) << 6) | dins_op);
1555 }
1557 void repl_qb (Register rd, int const8) { emit_long((special3_op << 26) | (low(const8, 8) << 16) | ((int)rd->encoding() << 11) | repl_qb_op << 6 | re1_op); }
1558 void replv_qb(Register rd, Register rt) { emit_long((special3_op << 26) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | replv_qb_op << 6 | re1_op ); }
1559 void repl_ph (Register rd, int const10) { emit_long((special3_op << 26) | (low(const10, 10) << 16) | ((int)rd->encoding() << 11) | repl_ph_op << 6 | re1_op); }
1560 void replv_ph(Register rd, Register rt) { emit_long((special3_op << 26) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | replv_ph_op << 6 | re1_op ); }
1562 void repl_ob (Register rd, int const8) { emit_long((special3_op << 26) | (low(const8, 8) << 16) | ((int)rd->encoding() << 11) | repl_ob_op << 6 | re2_op); }
1563 void replv_ob(Register rd, Register rt) { emit_long((special3_op << 26) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | replv_ob_op << 6 | re2_op ); }
1564 void repl_qh (Register rd, int const10) { emit_long((special3_op << 26) | (low(const10, 10) << 16) | ((int)rd->encoding() << 11) | repl_qh_op << 6 | re2_op); }
1565 void replv_qh(Register rd, Register rt) { emit_long((special3_op << 26) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | replv_qh_op << 6 | re2_op ); }
1566 void repl_pw (Register rd, int const10) { emit_long((special3_op << 26) | (low(const10, 10) << 16) | ((int)rd->encoding() << 11) | repl_pw_op << 6 | re2_op); }
1567 void replv_pw(Register rd, Register rt) { emit_long((special3_op << 26) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | replv_pw_op << 6 | re2_op ); }
1569 void sdc1(FloatRegister ft, Register base, int off) { emit_long(insn_ORRI(sdc1_op, (int)base->encoding(), (int)ft->encoding(), off)); }
1570 void sdc1(FloatRegister ft, Address dst);
1571 void swc1(FloatRegister ft, Register base, int off) { emit_long(insn_ORRI(swc1_op, (int)base->encoding(), (int)ft->encoding(), off)); }
1572 void swc1(FloatRegister ft, Address dst);
1575 void int3();
1576 static void print_instruction(int);
1577 int patched_branch(int dest_pos, int inst, int inst_pos);
1578 int branch_destination(int inst, int pos);
1580 /* Godson3 extension */
1582 // gssq/gslq/gssqc1/gslqc1: vAddr = sign_extend(offset << 4 ) + GPR[base]. Therefore, the off should be ">> 4".
1583 void gslq(Register rq, Register rt, Register base, int off) {
1584 off = off >> 4;
1585 assert(is_simm(off, 9),"gslq: off exceeds 9 bits");
1586 emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | 0 << 15 | (low(off, 9) << 6) | gslq_op | (int)rq->encoding() );
1587 }
1589 void gssq(Register rq, Register rt, Register base, int off) {
1590 off = off >> 4;
1591 assert(is_simm(off, 9),"gssq: off exceeds 9 bits");
1592 emit_long((gs_swc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | 0 << 15 | (low(off, 9) << 6) | gssq_op | (int)rq->encoding() );
1593 }
1595 void gsandn(Register rd, Register rs, Register rt) {
1596 emit_long((special2_op << 26) | ((int)rs->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | (18 << 6) | gs0x03_op );
1597 }
1599 void gsorn(Register rd, Register rs, Register rt) {
1600 emit_long((special2_op << 26) | ((int)rs->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | (18 << 6) | gs0x06_op );
1601 }
1603 //LDC2 & SDC2
1604 #define INSN(OPS, OP) \
1605 assert(is_simm(off, 8), "NAME: off exceeds 8 bits"); \
1606 assert(UseLoongsonISA, "check LoongISA"); \
1607 emit_long( (OPS << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | \
1608 ((int)index->encoding() << 11) | (low(off, 8) << 3) | OP);
1610 #define INSN_LDC2(NAME, op) \
1611 void NAME(Register rt, Register base, Register index, int off) { \
1612 INSN(gs_ldc2_op, op) \
1613 }
1615 #define INSN_LDC2_F(NAME, op) \
1616 void NAME(FloatRegister rt, Register base, Register index, int off) { \
1617 INSN(gs_ldc2_op, op) \
1618 }
1620 #define INSN_SDC2(NAME, op) \
1621 void NAME(Register rt, Register base, Register index, int off) { \
1622 INSN(gs_sdc2_op, op) \
1623 }
1625 #define INSN_SDC2_F(NAME, op) \
1626 void NAME(FloatRegister rt, Register base, Register index, int off) { \
1627 INSN(gs_sdc2_op, op) \
1628 }
1630 /*
1631 void gslbx(Register rt, Register base, Register index, int off) {
1632 assert(is_simm(off, 8), "gslbx: off exceeds 8 bits");
1633 assert(UseLoongsonISA, "check LoongISA");
1634 emit_long( (gs_ldc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) |
1635 ((int)index->encoding() << 11) | (low(off, 8) << 3) | gslbx_op);
1636 void gslbx(Register rt, Register base, Register index, int off) {INSN(gs_ldc2_op, gslbx_op);}
1638 INSN_LDC2(gslbx, gslbx_op)
1639 INSN_LDC2(gslhx, gslhx_op)
1640 INSN_LDC2(gslwx, gslwx_op)
1641 INSN_LDC2(gsldx, gsldx_op)
1642 INSN_LDC2_F(gslwxc1, gslwxc1_op)
1643 INSN_LDC2_F(gsldxc1, gsldxc1_op)
1645 INSN_SDC2(gssbx, gssbx_op)
1646 INSN_SDC2(gsshx, gsshx_op)
1647 INSN_SDC2(gsswx, gsswx_op)
1648 INSN_SDC2(gssdx, gssdx_op)
1649 INSN_SDC2_F(gsswxc1, gsswxc1_op)
1650 INSN_SDC2_F(gssdxc1, gssdxc1_op)
1651 */
1652 void gslbx(Register rt, Register base, Register index, int off) {INSN(gs_ldc2_op, gslbx_op) }
1653 void gslhx(Register rt, Register base, Register index, int off) {INSN(gs_ldc2_op, gslhx_op) }
1654 void gslwx(Register rt, Register base, Register index, int off) {INSN(gs_ldc2_op, gslwx_op) }
1655 void gsldx(Register rt, Register base, Register index, int off) {INSN(gs_ldc2_op, gsldx_op) }
1656 void gslwxc1(FloatRegister rt, Register base, Register index, int off) {INSN(gs_ldc2_op, gslwxc1_op) }
1657 void gsldxc1(FloatRegister rt, Register base, Register index, int off) {INSN(gs_ldc2_op, gsldxc1_op) }
1659 void gssbx(Register rt, Register base, Register index, int off) {INSN(gs_sdc2_op, gssbx_op) }
1660 void gsshx(Register rt, Register base, Register index, int off) {INSN(gs_sdc2_op, gsshx_op) }
1661 void gsswx(Register rt, Register base, Register index, int off) {INSN(gs_sdc2_op, gsswx_op) }
1662 void gssdx(Register rt, Register base, Register index, int off) {INSN(gs_sdc2_op, gssdx_op) }
1663 void gsswxc1(FloatRegister rt, Register base, Register index, int off) {INSN(gs_sdc2_op, gsswxc1_op) }
1664 void gssdxc1(FloatRegister rt, Register base, Register index, int off) {INSN(gs_sdc2_op, gssdxc1_op) }
1666 #undef INSN
1667 #undef INSN_LDC2
1668 #undef INSN_LDC2_F
1669 #undef INSN_SDC2
1670 #undef INSN_SDC2_F
1673 public:
1674 // Creation
1675 Assembler(CodeBuffer* code) : AbstractAssembler(code) {
1676 #ifdef CHECK_DELAY
1677 delay_state = no_delay;
1678 #endif
1679 }
1681 // Decoding
1682 static address locate_operand(address inst, WhichOperand which);
1683 static address locate_next_instruction(address inst);
1684 };
1687 // MacroAssembler extends Assembler by frequently used macros.
1688 //
1689 // Instructions for which a 'better' code sequence exists depending
1690 // on arguments should also go in here.
1692 class MacroAssembler: public Assembler {
1693 friend class LIR_Assembler;
1694 friend class Runtime1; // as_Address()
1696 public:
1697 static intptr_t i[32];
1698 static float f[32];
1699 static void print(outputStream *s);
1701 static int i_offset(unsigned int k);
1702 static int f_offset(unsigned int k);
1704 static void save_registers(MacroAssembler *masm);
1705 static void restore_registers(MacroAssembler *masm);
1707 protected:
1709 Address as_Address(AddressLiteral adr);
1710 Address as_Address(ArrayAddress adr);
1712 // Support for VM calls
1713 //
1714 // This is the base routine called by the different versions of call_VM_leaf. The interpreter
1715 // may customize this version by overriding it for its purposes (e.g., to save/restore
1716 // additional registers when doing a VM call).
1717 #ifdef CC_INTERP
1718 // c++ interpreter never wants to use interp_masm version of call_VM
1719 #define VIRTUAL
1720 #else
1721 #define VIRTUAL virtual
1722 #endif
1724 VIRTUAL void call_VM_leaf_base(
1725 address entry_point, // the entry point
1726 int number_of_arguments // the number of arguments to pop after the call
1727 );
1729 // This is the base routine called by the different versions of call_VM. The interpreter
1730 // may customize this version by overriding it for its purposes (e.g., to save/restore
1731 // additional registers when doing a VM call).
1732 //
1733 // If no java_thread register is specified (noreg) than rdi will be used instead. call_VM_base
1734 // returns the register which contains the thread upon return. If a thread register has been
1735 // specified, the return value will correspond to that register. If no last_java_sp is specified
1736 // (noreg) than rsp will be used instead.
1737 VIRTUAL void call_VM_base( // returns the register containing the thread upon return
1738 Register oop_result, // where an oop-result ends up if any; use noreg otherwise
1739 Register java_thread, // the thread if computed before ; use noreg otherwise
1740 Register last_java_sp, // to set up last_Java_frame in stubs; use noreg otherwise
1741 address entry_point, // the entry point
1742 int number_of_arguments, // the number of arguments (w/o thread) to pop after the call
1743 bool check_exceptions // whether to check for pending exceptions after return
1744 );
1746 // These routines should emit JVMTI PopFrame and ForceEarlyReturn handling code.
1747 // The implementation is only non-empty for the InterpreterMacroAssembler,
1748 // as only the interpreter handles PopFrame and ForceEarlyReturn requests.
1749 virtual void check_and_handle_popframe(Register java_thread);
1750 virtual void check_and_handle_earlyret(Register java_thread);
1752 void call_VM_helper(Register oop_result, address entry_point, int number_of_arguments, bool check_exceptions = true);
1754 // helpers for FPU flag access
1755 // tmp is a temporary register, if none is available use noreg
1756 //void save_rax (Register tmp);
1757 //void restore_rax(Register tmp);
1759 public:
1760 MacroAssembler(CodeBuffer* code) : Assembler(code) {}
1762 // Support for NULL-checks
1763 //
1764 // Generates code that causes a NULL OS exception if the content of reg is NULL.
1765 // If the accessed location is M[reg + offset] and the offset is known, provide the
1766 // offset. No explicit code generation is needed if the offset is within a certain
1767 // range (0 <= offset <= page_size).
1768 // use "teq 83, reg" in mips now, by yjl 6/20/2005
1769 void null_check(Register reg, int offset = -1);
1770 static bool needs_explicit_null_check(intptr_t offset);
1772 // Required platform-specific helpers for Label::patch_instructions.
1773 // They _shadow_ the declarations in AbstractAssembler, which are undefined.
1774 void pd_patch_instruction(address branch, address target);
1776 // Alignment
1777 void align(int modulus);
1779 // Misc
1780 //void fat_nop(); // 5 byte nop
1782 // Stack frame creation/removal
1783 void enter();
1784 void leave();
1786 // Support for getting the JavaThread pointer (i.e.; a reference to thread-local information)
1787 // The pointer will be loaded into the thread register.
1788 void get_thread(Register thread);
1791 // Support for VM calls
1792 //
1793 // It is imperative that all calls into the VM are handled via the call_VM macros.
1794 // They make sure that the stack linkage is setup correctly. call_VM's correspond
1795 // to ENTRY/ENTRY_X entry points while call_VM_leaf's correspond to LEAF entry points.
1798 void call_VM(Register oop_result,
1799 address entry_point,
1800 bool check_exceptions = true);
1801 void call_VM(Register oop_result,
1802 address entry_point,
1803 Register arg_1,
1804 bool check_exceptions = true);
1805 void call_VM(Register oop_result,
1806 address entry_point,
1807 Register arg_1, Register arg_2,
1808 bool check_exceptions = true);
1809 void call_VM(Register oop_result,
1810 address entry_point,
1811 Register arg_1, Register arg_2, Register arg_3,
1812 bool check_exceptions = true);
1813 // Super call_VM calls - correspond to MacroAssembler::call_VM(_leaf) calls
1814 void super_call_VM_leaf(address entry_point);
1815 void super_call_VM_leaf(address entry_point, Register arg_1);
1816 void super_call_VM_leaf(address entry_point, Register arg_1, Register arg_2);
1817 void super_call_VM_leaf(address entry_point,
1818 Register arg_1, Register arg_2, Register arg_3);
1820 // Overloadings with last_Java_sp
1821 void call_VM(Register oop_result,
1822 Register last_java_sp,
1823 address entry_point,
1824 int number_of_arguments = 0,
1825 bool check_exceptions = true);
1826 void call_VM(Register oop_result,
1827 Register last_java_sp,
1828 address entry_point,
1829 Register arg_1, bool
1830 check_exceptions = true);
1831 void call_VM(Register oop_result,
1832 Register last_java_sp,
1833 address entry_point,
1834 Register arg_1, Register arg_2,
1835 bool check_exceptions = true);
1836 void call_VM(Register oop_result,
1837 Register last_java_sp,
1838 address entry_point,
1839 Register arg_1, Register arg_2, Register arg_3,
1840 bool check_exceptions = true);
1842 void call_VM_leaf(address entry_point,
1843 int number_of_arguments = 0);
1844 void call_VM_leaf(address entry_point,
1845 Register arg_1);
1846 void call_VM_leaf(address entry_point,
1847 Register arg_1, Register arg_2);
1848 void call_VM_leaf(address entry_point,
1849 Register arg_1, Register arg_2, Register arg_3);
1851 // last Java Frame (fills frame anchor)
1852 void set_last_Java_frame(Register thread,
1853 Register last_java_sp,
1854 Register last_java_fp,
1855 address last_java_pc);
1857 // thread in the default location (r15_thread on 64bit)
1858 void set_last_Java_frame(Register last_java_sp,
1859 Register last_java_fp,
1860 address last_java_pc);
1862 void reset_last_Java_frame(Register thread, bool clear_fp, bool clear_pc);
1864 // thread in the default location (r15_thread on 64bit)
1865 void reset_last_Java_frame(bool clear_fp, bool clear_pc);
1867 // Stores
1868 void store_check(Register obj); // store check for obj - register is destroyed afterwards
1869 void store_check(Register obj, Address dst); // same as above, dst is exact store location (reg. is destroyed)
1872 void g1_write_barrier_pre(Register obj,
1873 #ifndef _LP64
1874 Register thread,
1875 #endif
1876 Register tmp,
1877 Register tmp2,
1878 bool tosca_live);
1879 void g1_write_barrier_post(Register store_addr,
1880 Register new_val,
1881 #ifndef _LP64
1882 Register thread,
1883 #endif
1884 Register tmp,
1885 Register tmp2);
1889 // split store_check(Register obj) to enhance instruction interleaving
1890 void store_check_part_1(Register obj);
1891 void store_check_part_2(Register obj);
1893 // C 'boolean' to Java boolean: x == 0 ? 0 : 1
1894 void c2bool(Register x);
1895 //add for compressedoops
1896 void load_klass(Register dst, Register src);
1897 void store_klass(Register dst, Register src);
1898 void load_prototype_header(Register dst, Register src);
1899 /*
1900 // C++ bool manipulation
1902 void movbool(Register dst, Address src);
1903 void movbool(Address dst, bool boolconst);
1904 void movbool(Address dst, Register src);
1905 void testbool(Register dst);
1907 // oop manipulations
1908 void load_klass(Register dst, Register src);
1909 void store_klass(Register dst, Register src);
1911 void load_prototype_header(Register dst, Register src);*/
1913 #ifdef _LP64
1914 void store_klass_gap(Register dst, Register src);
1916 void load_heap_oop(Register dst, Address src);
1917 void store_heap_oop(Address dst, Register src);
1918 void encode_heap_oop(Register r);
1919 void decode_heap_oop(Register r);
1920 void encode_heap_oop_not_null(Register r);
1921 void decode_heap_oop_not_null(Register r);
1922 void encode_heap_oop_not_null(Register dst, Register src);
1923 void decode_heap_oop_not_null(Register dst, Register src);
1925 void encode_klass_not_null(Register r);
1926 void decode_klass_not_null(Register r);
1927 void encode_klass_not_null(Register dst, Register src);
1928 void decode_klass_not_null(Register dst, Register src);
1930 //void set_narrow_oop(Register dst, jobject obj);
1932 // Returns the byte size of the instructions generated by decode_klass_not_null()
1933 // when compressed klass pointers are being used.
1934 static int instr_size_for_decode_klass_not_null();
1936 // if heap base register is used - reinit it with the correct value
1937 void reinit_heapbase();
1938 DEBUG_ONLY(void verify_heapbase(const char* msg);)
1940 #endif // _LP64
1942 void incrementl(Register reg, int value = 1);
1944 void decrementl(Register reg, int value = 1);
1946 /*
1947 // Int division/remainder for Java
1948 // (as idivl, but checks for special case as described in JVM spec.)
1949 // returns idivl instruction offset for implicit exception handling
1950 int corrected_idivl(Register reg);
1952 // Long division/remainder for Java
1953 // (as idivq, but checks for special case as described in JVM spec.)
1954 // returns idivq instruction offset for implicit exception handling
1955 int corrected_idivq(Register reg);
1956 */
1958 void int3();
1959 /*
1960 // Long operation macros for a 32bit cpu
1961 // Long negation for Java
1962 void lneg(Register hi, Register lo);
1964 // Long multiplication for Java
1965 // (destroys contents of eax, ebx, ecx and edx)
1966 void lmul(int x_rsp_offset, int y_rsp_offset); // rdx:rax = x * y
1968 // Long shifts for Java
1969 // (semantics as described in JVM spec.)
1970 void lshl(Register hi, Register lo); // hi:lo << (rcx & 0x3f)
1971 void lshr(Register hi, Register lo, bool sign_extension = false); // hi:lo >> (rcx & 0x3f)
1973 // Long compare for Java
1974 // (semantics as described in JVM spec.)
1975 void lcmp2int(Register x_hi, Register x_lo, Register y_hi, Register y_lo); // x_hi = lcmp(x, y)
1978 // misc
1979 */
1980 // Sign extension
1981 #ifdef _LP64
1982 void sign_extend_short(Register reg) { /*dsll32(reg, reg, 16); dsra32(reg, reg, 16);*/ seh(reg, reg); }
1983 void sign_extend_byte(Register reg) { /*dsll32(reg, reg, 24); dsra32(reg, reg, 24);*/ seb(reg, reg); }
1984 #else
1985 void sign_extend_short(Register reg) { /*sll(reg, reg, 16); sra(reg, reg, 16);*/ seh(reg, reg); }
1986 void sign_extend_byte(Register reg) { /*sll(reg, reg, 24); sra(reg, reg, 24);*/ seb(reg, reg);}
1987 #endif
1988 void rem_s(FloatRegister fd, FloatRegister fs, FloatRegister ft, FloatRegister tmp);
1989 void rem_d(FloatRegister fd, FloatRegister fs, FloatRegister ft, FloatRegister tmp);
1991 // Inlined sin/cos generator for Java; must not use CPU instruction
1992 // directly on Intel as it does not have high enough precision
1993 // outside of the range [-pi/4, pi/4]. Extra argument indicate the
1994 // number of FPU stack slots in use; all but the topmost will
1995 // require saving if a slow case is necessary. Assumes argument is
1996 // on FP TOS; result is on FP TOS. No cpu registers are changed by
1997 // this code.
1998 void trigfunc(char trig, int num_fpu_regs_in_use = 1);
1999 /*
2000 // branch to L if FPU flag C2 is set/not set
2001 // tmp is a temporary register, if none is available use noreg
2002 void jC2 (Register tmp, Label& L);
2003 void jnC2(Register tmp, Label& L);
2005 // Pop ST (ffree & fincstp combined)
2006 void fpop();
2008 // pushes double TOS element of FPU stack on CPU stack; pops from FPU stack
2009 void push_fTOS();
2011 // pops double TOS element from CPU stack and pushes on FPU stack
2012 void pop_fTOS();
2014 void empty_FPU_stack();
2016 void push_IU_state();
2017 void pop_IU_state();
2019 void push_FPU_state();
2020 void pop_FPU_state();
2022 void push_CPU_state();
2023 void pop_CPU_state();
2025 // Round up to a power of two
2026 void round_to(Register reg, int modulus);
2028 // Callee saved registers handling
2029 void push_callee_saved_registers();
2030 void pop_callee_saved_registers();
2031 */
2032 // allocation
2033 void eden_allocate(
2034 Register obj, // result: pointer to object after successful allocation
2035 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise
2036 int con_size_in_bytes, // object size in bytes if known at compile time
2037 Register t1, // temp register
2038 Register t2,
2039 Label& slow_case // continuation point if fast allocation fails
2040 );
2041 void tlab_allocate(
2042 Register obj, // result: pointer to object after successful allocation
2043 Register var_size_in_bytes, // object size in bytes if unknown at compile time; invalid otherwise
2044 int con_size_in_bytes, // object size in bytes if known at compile time
2045 Register t1, // temp register
2046 Register t2, // temp register
2047 Label& slow_case // continuation point if fast allocation fails
2048 );
2049 void tlab_refill(Label& retry_tlab, Label& try_eden, Label& slow_case);
2051 // void set_word_if_not_zero(Register reg); // sets reg to 1 if not zero, otherwise 0
2054 // Debugging
2056 // only if +VerifyOops
2057 void verify_oop(Register reg, const char* s = "broken oop");
2058 void verify_oop_addr(Address addr, const char * s = "broken oop addr");
2059 void verify_oop_subroutine();
2060 // TODO: verify method and klass metadata (compare against vptr?)
2061 void _verify_method_ptr(Register reg, const char * msg, const char * file, int line) {}
2062 void _verify_klass_ptr(Register reg, const char * msg, const char * file, int line){}
2064 #define verify_method_ptr(reg) _verify_method_ptr(reg, "broken method " #reg, __FILE__, __LINE__)
2065 #define verify_klass_ptr(reg) _verify_klass_ptr(reg, "broken klass " #reg, __FILE__, __LINE__)
2067 // only if +VerifyFPU
2068 void verify_FPU(int stack_depth, const char* s = "illegal FPU state");
2070 // prints msg, dumps registers and stops execution
2071 void stop(const char* msg);
2073 // prints msg and continues
2074 void warn(const char* msg);
2076 static void debug(char* msg/*, RegistersForDebugging* regs*/);
2077 static void debug32(int rdi, int rsi, int rbp, int rsp, int rbx, int rdx, int rcx, int rax, int eip, char* msg);
2078 static void debug64(char* msg, int64_t pc, int64_t regs[]);
2080 void print_reg(Register reg);
2081 void print_reg(FloatRegister reg);
2082 //void os_breakpoint();
2084 void untested() { stop("untested"); }
2086 void unimplemented(const char* what = "") { char* b = new char[1024]; jio_snprintf(b, sizeof(b), "unimplemented: %s", what); stop(b); }
2088 void should_not_reach_here() { stop("should not reach here"); }
2090 void print_CPU_state();
2092 // Stack overflow checking
2093 void bang_stack_with_offset(int offset) {
2094 // stack grows down, caller passes positive offset
2095 assert(offset > 0, "must bang with negative offset");
2096 if (offset <= 32768) {
2097 sw(A0, SP, -offset);
2098 } else {
2099 #ifdef _LP64
2100 li(AT, offset);
2101 dsub(AT, SP, AT);
2102 #else
2103 move(AT, offset);
2104 sub(AT, SP, AT);
2105 #endif
2106 sw(A0, AT, 0);
2107 }
2108 }
2110 // Writes to stack successive pages until offset reached to check for
2111 // stack overflow + shadow pages. Also, clobbers tmp
2112 void bang_stack_size(Register size, Register tmp);
2113 virtual RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr,
2114 Register tmp,
2115 int offset);
2117 // Support for serializing memory accesses between threads
2118 void serialize_memory(Register thread, Register tmp);
2120 //void verify_tlab();
2121 void verify_tlab(Register t1, Register t2);
2123 // Biased locking support
2124 // lock_reg and obj_reg must be loaded up with the appropriate values.
2125 // swap_reg must be rax, and is killed.
2126 // tmp_reg is optional. If it is supplied (i.e., != noreg) it will
2127 // be killed; if not supplied, push/pop will be used internally to
2128 // allocate a temporary (inefficient, avoid if possible).
2129 // Optional slow case is for implementations (interpreter and C1) which branch to
2130 // slow case directly. Leaves condition codes set for C2's Fast_Lock node.
2131 // Returns offset of first potentially-faulting instruction for null
2132 // check info (currently consumed only by C1). If
2133 // swap_reg_contains_mark is true then returns -1 as it is assumed
2134 // the calling code has already passed any potential faults.
2135 int biased_locking_enter(Register lock_reg, Register obj_reg,
2136 Register swap_reg, Register tmp_reg,
2137 bool swap_reg_contains_mark,
2138 Label& done, Label* slow_case = NULL,
2139 BiasedLockingCounters* counters = NULL);
2140 void biased_locking_exit (Register obj_reg, Register temp_reg, Label& done);
2143 // Calls
2145 void call(address entry);
2146 void call(address entry, relocInfo::relocType rtype);
2147 void call(address entry, RelocationHolder& rh);
2148 // Emit the CompiledIC call idiom
2149 void ic_call(address entry);
2151 void jmp(address entry);
2152 void jmp(address entry, relocInfo::relocType rtype);
2154 // Argument ops
2155 /*inline void store_int_argument(Register s, Argument& a);
2156 inline void store_long_argument(Register s, Argument& a);
2157 inline void store_float_argument(FloatRegister s, Argument& a);
2158 inline void store_double_argument(FloatRegister s, Argument& a);
2159 inline void store_ptr_argument(Register s, Argument& a);*/
2160 inline void store_int_argument(Register s, Argument &a) {
2161 if(a.is_Register()) {
2162 move(a.as_Register(), s);
2163 } else {
2164 sw(s, a.as_caller_address());
2165 }
2166 }
2168 inline void store_long_argument(Register s, Argument &a) {
2169 Argument a1 = a.successor();
2170 if(a.is_Register() && a1.is_Register()) {
2171 move(a.as_Register(), s);
2172 move(a.as_Register(), s);
2173 } else {
2174 sd(s, a.as_caller_address());
2175 }
2176 }
2178 inline void store_float_argument(FloatRegister s, Argument &a) {
2179 if(a.is_Register()) {
2180 mov_s(a.as_FloatRegister(), s);
2181 } else {
2182 swc1(s, a.as_caller_address());
2183 }
2184 }
2185 inline void store_double_argument(FloatRegister s, Argument &a) {
2186 if(a.is_Register()) {
2187 mov_d(a.as_FloatRegister(), s);
2188 } else {
2189 sdc1(s, a.as_caller_address());
2190 }
2191 }
2193 inline void store_ptr_argument(Register s, Argument &a) {
2194 if(a.is_Register()) {
2195 move(a.as_Register(), s);
2196 } else {
2197 st_ptr(s, a.as_caller_address());
2198 }
2199 }
2201 // Load and store values by size and signed-ness
2202 void load_sized_value(Register dst, Address src, size_t size_in_bytes, bool is_signed, Register dst2 = noreg);
2203 void store_sized_value(Address dst, Register src, size_t size_in_bytes, Register src2 = noreg);
2205 // interface method calling
2206 void lookup_interface_method(Register recv_klass,
2207 Register intf_klass,
2208 RegisterOrConstant itable_index,
2209 Register method_result,
2210 Register scan_temp,
2211 Label& no_such_interface);
2212 // virtual method calling
2213 void lookup_virtual_method(Register recv_klass,
2214 RegisterOrConstant vtable_index,
2215 Register method_result);
2217 // ld_ptr will perform lw for 32 bit VMs and ld for 64 bit VMs
2218 // st_ptr will perform sw for 32 bit VMs and sd for 64 bit VMs
2219 inline void ld_ptr(Register rt, Address a){
2220 #ifdef _LP64
2221 ld(rt, a.base(), a.disp());
2222 #else
2223 lw(rt, a.base(), a.disp());
2224 #endif
2225 }
2226 inline void ld_ptr(Register rt, Register base, int offset16){
2227 #ifdef _LP64
2228 ld(rt, base, offset16);
2229 #else
2230 lw(rt, base, offset16);
2231 #endif
2233 }
2234 inline void st_ptr(Register rt, Address a){
2235 #ifdef _LP64
2236 sd(rt, a.base(), a.disp());
2237 #else
2238 sw(rt, a.base(), a.disp());
2239 #endif
2240 }
2241 inline void st_ptr(Register rt, Register base, int offset16) {
2242 #ifdef _LP64
2243 sd(rt, base, offset16);
2244 #else
2245 sw(rt, base, offset16);
2246 #endif
2248 }
2250 void ld_ptr(Register rt, Register offset, Register base);
2251 void st_ptr(Register rt, Register offset, Register base);
2253 // ld_long will perform lw for 32 bit VMs and ld for 64 bit VMs
2254 // st_long will perform sw for 32 bit VMs and sd for 64 bit VMs
2255 inline void ld_long(Register rt, Register base, int offset16);
2256 inline void st_long(Register rt, Register base, int offset16);
2257 inline void ld_long(Register rt, Address a);
2258 inline void st_long(Register rt, Address a);
2261 void ld_long(Register rt, Register offset, Register base);
2262 void st_long(Register rt, Register offset, Register base);
2263 // Regular vs. d* versions
2264 inline void addu_long(Register rd, Register rs, Register rt) {
2265 #ifdef _LP64
2266 daddu(rd, rs, rt);
2267 #else
2268 addu(rd, rs, rt);
2269 #endif
2270 }
2271 inline void addu_long(Register rd, Register rs, long imm32_64) {
2272 #ifdef _LP64
2273 daddiu(rd, rs, imm32_64);
2274 #else
2275 addiu(rd, rs, imm32_64);
2276 #endif
2278 }
2280 // Floating
2281 public:
2282 // swap the two byte of the low 16-bit halfword
2283 // this directive will use AT, be sure the high 16-bit of reg is zero
2284 // by yjl 6/28/2005
2285 void hswap(Register reg);
2286 void huswap(Register reg);
2288 // convert big endian integer to little endian integer
2289 // by yjl 6/29/2005
2290 void swap(Register reg);
2292 // implement the x86 instruction semantic
2293 // if c_reg == *dest then *dest <= x_reg
2294 // else c_reg <= *dest
2295 // the AT indicate if xchg occurred, 1 for xchged, else 0
2296 // by yjl 6/28/2005
2297 void cmpxchg(Register x_reg, Address dest, Register c_reg);
2298 #ifdef _LP64
2299 void cmpxchg32(Register x_reg, Address dest, Register c_reg);
2300 #endif
2301 void cmpxchg8(Register x_regLo, Register x_regHi, Address dest, Register c_regLo, Register c_regHi);
2305 void round_to(Register reg, int modulus) {
2306 assert_different_registers(reg, AT);
2307 increment(reg, modulus - 1);
2308 move(AT, - modulus);
2309 andr(reg, reg, AT);
2310 }
2312 //pop & push, added by aoqi
2313 #ifdef _LP64
2314 void extend_sign(Register rh, Register rl) { stop("extend_sign"); }
2315 void neg(Register reg) { dsubu(reg, R0, reg); }
2316 void push (Register reg) { sd (reg, SP, -8); daddi(SP, SP, -8); }
2317 void push (FloatRegister reg) { sdc1(reg, SP, -8); daddi(SP, SP, -8); }
2318 void pop (Register reg) { ld (reg, SP, 0); daddi(SP, SP, 8); }
2319 void pop (FloatRegister reg) { ldc1(reg, SP, 0); daddi(SP, SP, 8); }
2320 void pop () { daddi(SP, SP, 8); }
2321 void pop2 () { daddi(SP, SP, 16); }
2322 #else
2323 void extend_sign(Register rh, Register rl) { sra(rh, rl, 31); }
2324 void neg(Register reg) { subu(reg, R0, reg); }
2325 void push (Register reg) { sw (reg, SP, -4); addi(SP, SP, -4); }
2326 void push (FloatRegister reg) { swc1(reg, SP, -4); addi(SP, SP, -4); }
2327 void pop (Register reg) { lw (reg, SP, 0); addi(SP, SP, 4); }
2328 void pop (FloatRegister reg) { lwc1(reg, SP, 0); addi(SP, SP, 4); }
2329 void pop () { addi(SP, SP, 4); }
2330 void pop2 () { addi(SP, SP, 8); }
2331 #endif
2332 void push2(Register reg1, Register reg2);
2333 void pop2 (Register reg1, Register reg2);
2334 void dpush (Register reg) { sd (reg, SP, -8); daddi(SP, SP, -8); }
2335 void dpop (Register reg) { ld (reg, SP, 0); daddi(SP, SP, 8); }
2337 /* branches may exceed 16-bit offset */
2338 void b_far(address entry);
2339 void b_far(Label& L);
2341 void bne_far (Register rs, Register rt, address entry);
2342 void bne_far (Register rs, Register rt, Label& L);
2344 void beq_far (Register rs, Register rt, address entry);
2345 void beq_far (Register rs, Register rt, Label& L);
2347 //move an 32-bit immediate to Register
2348 void move(Register reg, int imm32) { li32(reg, imm32); }
2349 void li (Register rd, long imm);
2350 void li (Register rd, address addr) { li(rd, (long)addr); }
2351 //replace move(Register reg, int imm)
2352 void li32(Register rd, int imm32); // sign-extends to 64 bits on mips64
2353 #ifdef _LP64
2354 void set64(Register d, jlong value);
2355 static int insts_for_set64(jlong value);
2357 void dli(Register rd, long imm) { li(rd, imm); }
2358 void li64(Register rd, long imm);
2359 void li48(Register rd, long imm);
2360 #endif
2362 #ifdef _LP64
2363 void move(Register rd, Register rs) { dadd(rd, rs, R0); }
2364 void move_u32(Register rd, Register rs) { addu32(rd, rs, R0); }
2365 #else
2366 void move(Register rd, Register rs) { add(rd, rs, R0); }
2367 #endif
2368 void dmove(Register rd, Register rs) { dadd(rd, rs, R0); }
2370 #ifdef _LP64
2371 void shl(Register reg, int sa) { dsll(reg, reg, sa); }
2372 void shr(Register reg, int sa) { dsrl(reg, reg, sa); }
2373 void sar(Register reg, int sa) { dsra(reg, reg, sa); }
2374 #else
2375 void shl(Register reg, int sa) { sll(reg, reg, sa); }
2376 void shr(Register reg, int sa) { srl(reg, reg, sa); }
2377 void sar(Register reg, int sa) { sra(reg, reg, sa); }
2378 #endif
2380 #ifndef PRODUCT
2381 static void pd_print_patched_instruction(address branch) {
2382 jint stub_inst = *(jint*) branch;
2383 print_instruction(stub_inst);
2384 ::tty->print("%s", " (unresolved)");
2386 }
2387 #endif
2389 // the follow two might use AT register, be sure you have no meanful data in AT before you call them
2390 void increment(Register reg, int imm);
2391 void decrement(Register reg, int imm);
2393 //FIXME
2394 void empty_FPU_stack(){/*need implemented*/};
2396 //we need 2 fun to save and resotre general register
2397 void pushad();
2398 void popad();
2400 // Test sub_klass against super_klass, with fast and slow paths.
2402 // The fast path produces a tri-state answer: yes / no / maybe-slow.
2403 // One of the three labels can be NULL, meaning take the fall-through.
2404 // If super_check_offset is -1, the value is loaded up from super_klass.
2405 // No registers are killed, except temp_reg.
2406 void check_klass_subtype_fast_path(Register sub_klass,
2407 Register super_klass,
2408 Register temp_reg,
2409 Label* L_success,
2410 Label* L_failure,
2411 Label* L_slow_path,
2412 RegisterOrConstant super_check_offset = RegisterOrConstant(-1));
2414 // The rest of the type check; must be wired to a corresponding fast path.
2415 // It does not repeat the fast path logic, so don't use it standalone.
2416 // The temp_reg and temp2_reg can be noreg, if no temps are available.
2417 // Updates the sub's secondary super cache as necessary.
2418 // If set_cond_codes, condition codes will be Z on success, NZ on failure.
2419 void check_klass_subtype_slow_path(Register sub_klass,
2420 Register super_klass,
2421 Register temp_reg,
2422 Register temp2_reg,
2423 Label* L_success,
2424 Label* L_failure,
2425 bool set_cond_codes = false);
2427 // Simplified, combined version, good for typical uses.
2428 // Falls through on failure.
2429 void check_klass_subtype(Register sub_klass,
2430 Register super_klass,
2431 Register temp_reg,
2432 Label& L_success);
2434 // method handles (JSR 292)
2435 Address argument_address(RegisterOrConstant arg_slot, int extra_slot_offset = 0);
2437 void get_vm_result (Register oop_result, Register thread);
2438 void get_vm_result_2(Register metadata_result, Register thread);
2439 #undef VIRTUAL
2440 void atomic_inc32(address counter_addr, int inc, Register tmp_reg1, Register tmp_reg2);
2442 void fast_lock(Register obj, Register box, Register tmp, Register scr);
2443 void fast_unlock(Register obj, Register box, Register tmp);
2444 };
2446 /**
2447 * class SkipIfEqual:
2448 *
2449 * Instantiating this class will result in assembly code being output that will
2450 * jump around any code emitted between the creation of the instance and it's
2451 * automatic destruction at the end of a scope block, depending on the value of
2452 * the flag passed to the constructor, which will be checked at run-time.
2453 */
2454 class SkipIfEqual {
2455 private:
2456 MacroAssembler* _masm;
2457 Label _label;
2459 public:
2460 SkipIfEqual(MacroAssembler*, const bool* flag_addr, bool value);
2461 ~SkipIfEqual();
2462 };
2464 #ifdef ASSERT
2465 inline bool AbstractAssembler::pd_check_instruction_mark() { return true; }
2466 #endif
2468 #endif // CPU_MIPS_VM_ASSEMBLER_MIPS_HPP