Mon, 18 Nov 2019 10:41:48 +0800
#10052 Backport of #9904 compiler/floatingpoint/TestFloatSyncJNIArgs.java failed
Reviewed-by: aoqi
1 /*
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2015, 2019, 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 {
40 public:
41 enum ScaleFactor {
42 no_scale = -1,
43 times_1 = 0,
44 times_2 = 1,
45 times_4 = 2,
46 times_8 = 3,
47 times_ptr = LP64_ONLY(times_8) NOT_LP64(times_4)
48 };
49 static ScaleFactor times(int size) {
50 assert(size >= 1 && size <= 8 && is_power_of_2(size), "bad scale size");
51 if (size == 8) return times_8;
52 if (size == 4) return times_4;
53 if (size == 2) return times_2;
54 return times_1;
55 }
57 private:
58 Register _base;
59 Register _index;
60 ScaleFactor _scale;
61 int _disp;
62 RelocationHolder _rspec;
64 // Easily misused constructors make them private
65 Address(address loc, RelocationHolder spec);
66 Address(int disp, address loc, relocInfo::relocType rtype);
67 Address(int disp, address loc, RelocationHolder spec);
69 public:
71 // creation
72 Address()
73 : _base(noreg),
74 _index(noreg),
75 _scale(no_scale),
76 _disp(0) {
77 }
79 // No default displacement otherwise Register can be implicitly
80 // converted to 0(Register) which is quite a different animal.
82 Address(Register base, int disp = 0)
83 : _base(base),
84 _index(noreg),
85 _scale(no_scale),
86 _disp(disp) {
87 assert_different_registers(_base, AT);
88 }
90 Address(Register base, Register index, ScaleFactor scale, int disp = 0)
91 : _base (base),
92 _index(index),
93 _scale(scale),
94 _disp (disp) {
95 assert(!index->is_valid() == (scale == Address::no_scale), "inconsistent address");
96 assert_different_registers(_base, _index, AT);
97 }
99 // The following two overloads are used in connection with the
100 // ByteSize type (see sizes.hpp). They simplify the use of
101 // ByteSize'd arguments in assembly code. Note that their equivalent
102 // for the optimized build are the member functions with int disp
103 // argument since ByteSize is mapped to an int type in that case.
104 //
105 // Note: DO NOT introduce similar overloaded functions for WordSize
106 // arguments as in the optimized mode, both ByteSize and WordSize
107 // are mapped to the same type and thus the compiler cannot make a
108 // distinction anymore (=> compiler errors).
110 #ifdef ASSERT
111 Address(Register base, ByteSize disp)
112 : _base(base),
113 _index(noreg),
114 _scale(no_scale),
115 _disp(in_bytes(disp)) {
116 assert_different_registers(_base, AT);
117 }
119 Address(Register base, Register index, ScaleFactor scale, ByteSize disp)
120 : _base(base),
121 _index(index),
122 _scale(scale),
123 _disp(in_bytes(disp)) {
124 assert(!index->is_valid() == (scale == Address::no_scale), "inconsistent address");
125 assert_different_registers(_base, _index, AT);
126 }
127 #endif // ASSERT
129 // accessors
130 bool uses(Register reg) const { return _base == reg || _index == reg; }
131 Register base() const { return _base; }
132 Register index() const { return _index; }
133 ScaleFactor scale() const { return _scale; }
134 int disp() const { return _disp; }
136 static Address make_array(ArrayAddress);
138 friend class Assembler;
139 friend class MacroAssembler;
140 friend class LIR_Assembler; // base/index/scale/disp
141 };
144 // Calling convention
145 class Argument VALUE_OBJ_CLASS_SPEC {
146 private:
147 int _number;
148 public:
149 enum {
150 #ifdef _LP64
151 n_register_parameters = 8, // 8 integer registers used to pass parameters
152 n_float_register_parameters = 8 // 8 float registers used to pass parameters
153 #else
154 n_register_parameters = 4, // 4 integer registers used to pass parameters
155 n_float_register_parameters = 4 // 4 float registers used to pass parameters
156 #endif
157 };
159 Argument(int number):_number(number){ }
160 Argument successor() {return Argument(number() + 1);}
162 int number()const {return _number;}
163 bool is_Register()const {return _number < n_register_parameters;}
164 bool is_FloatRegister()const {return _number < n_float_register_parameters;}
166 Register as_Register()const {
167 assert(is_Register(), "must be a register argument");
168 return ::as_Register(A0->encoding() + _number);
169 }
170 FloatRegister as_FloatRegister()const {
171 assert(is_FloatRegister(), "must be a float register argument");
172 return ::as_FloatRegister(F12->encoding() + _number);
173 }
175 Address as_caller_address()const {return Address(SP, (number() LP64_ONLY( -n_register_parameters)) * wordSize);}
176 };
180 //
181 // AddressLiteral has been split out from Address because operands of this type
182 // need to be treated specially on 32bit vs. 64bit platforms. By splitting it out
183 // the few instructions that need to deal with address literals are unique and the
184 // MacroAssembler does not have to implement every instruction in the Assembler
185 // in order to search for address literals that may need special handling depending
186 // on the instruction and the platform. As small step on the way to merging i486/amd64
187 // directories.
188 //
189 class AddressLiteral VALUE_OBJ_CLASS_SPEC {
190 friend class ArrayAddress;
191 RelocationHolder _rspec;
192 // Typically we use AddressLiterals we want to use their rval
193 // However in some situations we want the lval (effect address) of the item.
194 // We provide a special factory for making those lvals.
195 bool _is_lval;
197 // If the target is far we'll need to load the ea of this to
198 // a register to reach it. Otherwise if near we can do rip
199 // relative addressing.
201 address _target;
203 protected:
204 // creation
205 AddressLiteral()
206 : _is_lval(false),
207 _target(NULL)
208 {}
210 public:
213 AddressLiteral(address target, relocInfo::relocType rtype);
215 AddressLiteral(address target, RelocationHolder const& rspec)
216 : _rspec(rspec),
217 _is_lval(false),
218 _target(target)
219 {}
220 #ifdef _LP64
221 // 32-bit complains about a multiple declaration for int*.
222 AddressLiteral(intptr_t* addr, relocInfo::relocType rtype = relocInfo::none)
223 : _target((address) addr),
224 _rspec(rspec_from_rtype(rtype, (address) addr)) {}
225 #endif
227 AddressLiteral addr() {
228 AddressLiteral ret = *this;
229 ret._is_lval = true;
230 return ret;
231 }
234 private:
236 address target() { return _target; }
237 bool is_lval() { return _is_lval; }
239 relocInfo::relocType reloc() const { return _rspec.type(); }
240 const RelocationHolder& rspec() const { return _rspec; }
242 friend class Assembler;
243 friend class MacroAssembler;
244 friend class Address;
245 friend class LIR_Assembler;
246 RelocationHolder rspec_from_rtype(relocInfo::relocType rtype, address addr) {
247 switch (rtype) {
248 case relocInfo::external_word_type:
249 return external_word_Relocation::spec(addr);
250 case relocInfo::internal_word_type:
251 return internal_word_Relocation::spec(addr);
252 case relocInfo::opt_virtual_call_type:
253 return opt_virtual_call_Relocation::spec();
254 case relocInfo::static_call_type:
255 return static_call_Relocation::spec();
256 case relocInfo::runtime_call_type:
257 return runtime_call_Relocation::spec();
258 case relocInfo::poll_type:
259 case relocInfo::poll_return_type:
260 return Relocation::spec_simple(rtype);
261 case relocInfo::none:
262 case relocInfo::oop_type:
263 // Oops are a special case. Normally they would be their own section
264 // but in cases like icBuffer they are literals in the code stream that
265 // we don't have a section for. We use none so that we get a literal address
266 // which is always patchable.
267 return RelocationHolder();
268 default:
269 ShouldNotReachHere();
270 return RelocationHolder();
271 }
272 }
274 };
276 // Convience classes
277 class RuntimeAddress: public AddressLiteral {
279 public:
281 RuntimeAddress(address target) : AddressLiteral(target, relocInfo::runtime_call_type) {}
283 };
285 class OopAddress: public AddressLiteral {
287 public:
289 OopAddress(address target) : AddressLiteral(target, relocInfo::oop_type){}
291 };
293 class ExternalAddress: public AddressLiteral {
295 public:
297 ExternalAddress(address target) : AddressLiteral(target, relocInfo::external_word_type){}
299 };
301 class InternalAddress: public AddressLiteral {
303 public:
305 InternalAddress(address target) : AddressLiteral(target, relocInfo::internal_word_type) {}
307 };
309 // x86 can do array addressing as a single operation since disp can be an absolute
310 // address amd64 can't. We create a class that expresses the concept but does extra
311 // magic on amd64 to get the final result
313 class ArrayAddress VALUE_OBJ_CLASS_SPEC {
314 private:
316 AddressLiteral _base;
317 Address _index;
319 public:
321 ArrayAddress() {};
322 ArrayAddress(AddressLiteral base, Address index): _base(base), _index(index) {};
323 AddressLiteral base() { return _base; }
324 Address index() { return _index; }
326 };
328 const int FPUStateSizeInWords = NOT_LP64(27) LP64_ONLY( 512 / wordSize);
330 // The MIPS LOONGSON Assembler: Pure assembler doing NO optimizations on the instruction
331 // level ; i.e., what you write is what you get. The Assembler is generating code into
332 // a CodeBuffer.
334 class Assembler : public AbstractAssembler {
335 friend class AbstractAssembler; // for the non-virtual hack
336 friend class LIR_Assembler; // as_Address()
337 friend class StubGenerator;
339 public:
340 enum Condition {
341 zero ,
342 notZero ,
343 equal ,
344 notEqual ,
345 less ,
346 lessEqual ,
347 greater ,
348 greaterEqual ,
349 below ,
350 belowEqual ,
351 above ,
352 aboveEqual
353 };
355 static const int LogInstructionSize = 2;
356 static const int InstructionSize = 1 << LogInstructionSize;
358 // opcode, highest 6 bits: bits[31...26]
359 enum ops {
360 special_op = 0x00, // special_ops
361 regimm_op = 0x01, // regimm_ops
362 j_op = 0x02,
363 jal_op = 0x03,
364 beq_op = 0x04,
365 bne_op = 0x05,
366 blez_op = 0x06,
367 bgtz_op = 0x07,
368 addi_op = 0x08,
369 addiu_op = 0x09,
370 slti_op = 0x0a,
371 sltiu_op = 0x0b,
372 andi_op = 0x0c,
373 ori_op = 0x0d,
374 xori_op = 0x0e,
375 lui_op = 0x0f,
376 cop0_op = 0x10, // cop0_ops
377 cop1_op = 0x11, // cop1_ops
378 gs_cop2_op = 0x12, // gs_cop2_ops
379 cop1x_op = 0x13, // cop1x_ops
380 beql_op = 0x14,
381 bnel_op = 0x15,
382 blezl_op = 0x16,
383 bgtzl_op = 0x17,
384 daddi_op = 0x18,
385 daddiu_op = 0x19,
386 ldl_op = 0x1a,
387 ldr_op = 0x1b,
388 special2_op = 0x1c, // special2_ops
389 msa_op = 0x1e, // msa_ops
390 special3_op = 0x1f, // special3_ops
391 lb_op = 0x20,
392 lh_op = 0x21,
393 lwl_op = 0x22,
394 lw_op = 0x23,
395 lbu_op = 0x24,
396 lhu_op = 0x25,
397 lwr_op = 0x26,
398 lwu_op = 0x27,
399 sb_op = 0x28,
400 sh_op = 0x29,
401 swl_op = 0x2a,
402 sw_op = 0x2b,
403 sdl_op = 0x2c,
404 sdr_op = 0x2d,
405 swr_op = 0x2e,
406 cache_op = 0x2f,
407 ll_op = 0x30,
408 lwc1_op = 0x31,
409 gs_lwc2_op = 0x32, //gs_lwc2_ops
410 pref_op = 0x33,
411 lld_op = 0x34,
412 ldc1_op = 0x35,
413 gs_ldc2_op = 0x36, //gs_ldc2_ops
414 ld_op = 0x37,
415 sc_op = 0x38,
416 swc1_op = 0x39,
417 gs_swc2_op = 0x3a, //gs_swc2_ops
418 scd_op = 0x3c,
419 sdc1_op = 0x3d,
420 gs_sdc2_op = 0x3e, //gs_sdc2_ops
421 sd_op = 0x3f
422 };
424 static const char *ops_name[];
426 //special family, the opcode is in low 6 bits.
427 enum special_ops {
428 sll_op = 0x00,
429 movci_op = 0x01,
430 srl_op = 0x02,
431 sra_op = 0x03,
432 sllv_op = 0x04,
433 srlv_op = 0x06,
434 srav_op = 0x07,
435 jr_op = 0x08,
436 jalr_op = 0x09,
437 movz_op = 0x0a,
438 movn_op = 0x0b,
439 syscall_op = 0x0c,
440 break_op = 0x0d,
441 sync_op = 0x0f,
442 mfhi_op = 0x10,
443 mthi_op = 0x11,
444 mflo_op = 0x12,
445 mtlo_op = 0x13,
446 dsllv_op = 0x14,
447 dsrlv_op = 0x16,
448 dsrav_op = 0x17,
449 mult_op = 0x18,
450 multu_op = 0x19,
451 div_op = 0x1a,
452 divu_op = 0x1b,
453 dmult_op = 0x1c,
454 dmultu_op = 0x1d,
455 ddiv_op = 0x1e,
456 ddivu_op = 0x1f,
457 add_op = 0x20,
458 addu_op = 0x21,
459 sub_op = 0x22,
460 subu_op = 0x23,
461 and_op = 0x24,
462 or_op = 0x25,
463 xor_op = 0x26,
464 nor_op = 0x27,
465 slt_op = 0x2a,
466 sltu_op = 0x2b,
467 dadd_op = 0x2c,
468 daddu_op = 0x2d,
469 dsub_op = 0x2e,
470 dsubu_op = 0x2f,
471 tge_op = 0x30,
472 tgeu_op = 0x31,
473 tlt_op = 0x32,
474 tltu_op = 0x33,
475 teq_op = 0x34,
476 tne_op = 0x36,
477 dsll_op = 0x38,
478 dsrl_op = 0x3a,
479 dsra_op = 0x3b,
480 dsll32_op = 0x3c,
481 dsrl32_op = 0x3e,
482 dsra32_op = 0x3f
483 };
485 static const char* special_name[];
487 //regimm family, the opcode is in rt[16...20], 5 bits
488 enum regimm_ops {
489 bltz_op = 0x00,
490 bgez_op = 0x01,
491 bltzl_op = 0x02,
492 bgezl_op = 0x03,
493 tgei_op = 0x08,
494 tgeiu_op = 0x09,
495 tlti_op = 0x0a,
496 tltiu_op = 0x0b,
497 teqi_op = 0x0c,
498 tnei_op = 0x0e,
499 bltzal_op = 0x10,
500 bgezal_op = 0x11,
501 bltzall_op = 0x12,
502 bgezall_op = 0x13,
503 bposge32_op = 0x1c,
504 bposge64_op = 0x1d,
505 synci_op = 0x1f,
506 };
508 static const char* regimm_name[];
510 //cop0 family, the ops is in bits[25...21], 5 bits
511 enum cop0_ops {
512 mfc0_op = 0x00,
513 dmfc0_op = 0x01,
514 //
515 mxgc0_op = 0x03, //MFGC0, DMFGC0, MTGC0
516 mtc0_op = 0x04,
517 dmtc0_op = 0x05,
518 rdpgpr_op = 0x0a,
519 inter_op = 0x0b,
520 wrpgpr_op = 0x0c
521 };
523 //cop1 family, the ops is in bits[25...21], 5 bits
524 enum cop1_ops {
525 mfc1_op = 0x00,
526 dmfc1_op = 0x01,
527 cfc1_op = 0x02,
528 mfhc1_op = 0x03,
529 mtc1_op = 0x04,
530 dmtc1_op = 0x05,
531 ctc1_op = 0x06,
532 mthc1_op = 0x07,
533 bc1f_op = 0x08,
534 single_fmt = 0x10,
535 double_fmt = 0x11,
536 word_fmt = 0x14,
537 long_fmt = 0x15,
538 ps_fmt = 0x16
539 };
542 //2 bist (bits[17...16]) of bc1x instructions (cop1)
543 enum bc_ops {
544 bcf_op = 0x0,
545 bct_op = 0x1,
546 bcfl_op = 0x2,
547 bctl_op = 0x3,
548 };
550 // low 6 bits of c_x_fmt instructions (cop1)
551 enum c_conds {
552 f_cond = 0x30,
553 un_cond = 0x31,
554 eq_cond = 0x32,
555 ueq_cond = 0x33,
556 olt_cond = 0x34,
557 ult_cond = 0x35,
558 ole_cond = 0x36,
559 ule_cond = 0x37,
560 sf_cond = 0x38,
561 ngle_cond = 0x39,
562 seq_cond = 0x3a,
563 ngl_cond = 0x3b,
564 lt_cond = 0x3c,
565 nge_cond = 0x3d,
566 le_cond = 0x3e,
567 ngt_cond = 0x3f
568 };
570 // low 6 bits of cop1 instructions
571 enum float_ops {
572 fadd_op = 0x00,
573 fsub_op = 0x01,
574 fmul_op = 0x02,
575 fdiv_op = 0x03,
576 fsqrt_op = 0x04,
577 fabs_op = 0x05,
578 fmov_op = 0x06,
579 fneg_op = 0x07,
580 froundl_op = 0x08,
581 ftruncl_op = 0x09,
582 fceill_op = 0x0a,
583 ffloorl_op = 0x0b,
584 froundw_op = 0x0c,
585 ftruncw_op = 0x0d,
586 fceilw_op = 0x0e,
587 ffloorw_op = 0x0f,
588 movf_f_op = 0x11,
589 movt_f_op = 0x11,
590 movz_f_op = 0x12,
591 movn_f_op = 0x13,
592 frecip_op = 0x15,
593 frsqrt_op = 0x16,
594 fcvts_op = 0x20,
595 fcvtd_op = 0x21,
596 fcvtw_op = 0x24,
597 fcvtl_op = 0x25,
598 fcvtps_op = 0x26,
599 fcvtspl_op = 0x28,
600 fpll_op = 0x2c,
601 fplu_op = 0x2d,
602 fpul_op = 0x2e,
603 fpuu_op = 0x2f
604 };
606 static const char* cop1_name[];
608 //cop1x family, the opcode is in low 6 bits.
609 enum cop1x_ops {
610 lwxc1_op = 0x00,
611 ldxc1_op = 0x01,
612 luxc1_op = 0x05,
613 swxc1_op = 0x08,
614 sdxc1_op = 0x09,
615 suxc1_op = 0x0d,
616 prefx_op = 0x0f,
618 alnv_ps_op = 0x1e,
619 madd_s_op = 0x20,
620 madd_d_op = 0x21,
621 madd_ps_op = 0x26,
622 msub_s_op = 0x28,
623 msub_d_op = 0x29,
624 msub_ps_op = 0x2e,
625 nmadd_s_op = 0x30,
626 nmadd_d_op = 0x31,
627 nmadd_ps_op = 0x36,
628 nmsub_s_op = 0x38,
629 nmsub_d_op = 0x39,
630 nmsub_ps_op = 0x3e
631 };
633 static const char* cop1x_name[];
635 //special2 family, the opcode is in low 6 bits.
636 enum special2_ops {
637 madd_op = 0x00,
638 maddu_op = 0x01,
639 mul_op = 0x02,
640 gs0x03_op = 0x03,
641 msub_op = 0x04,
642 msubu_op = 0x05,
643 gs0x06_op = 0x06,
644 gsemul2_op = 0x07,
645 gsemul3_op = 0x08,
646 gsemul4_op = 0x09,
647 gsemul5_op = 0x0a,
648 gsemul6_op = 0x0b,
649 gsemul7_op = 0x0c,
650 gsemul8_op = 0x0d,
651 gsemul9_op = 0x0e,
652 gsemul10_op = 0x0f,
653 gsmult_op = 0x10,
654 gsdmult_op = 0x11,
655 gsmultu_op = 0x12,
656 gsdmultu_op = 0x13,
657 gsdiv_op = 0x14,
658 gsddiv_op = 0x15,
659 gsdivu_op = 0x16,
660 gsddivu_op = 0x17,
661 gsmod_op = 0x1c,
662 gsdmod_op = 0x1d,
663 gsmodu_op = 0x1e,
664 gsdmodu_op = 0x1f,
665 clz_op = 0x20,
666 clo_op = 0x21,
667 xctx_op = 0x22, //ctz, cto, dctz, dcto, gsX
668 gsrxr_x_op = 0x23, //gsX
669 dclz_op = 0x24,
670 dclo_op = 0x25,
671 gsle_op = 0x26,
672 gsgt_op = 0x27,
673 gs86j_op = 0x28,
674 gsloop_op = 0x29,
675 gsaj_op = 0x2a,
676 gsldpc_op = 0x2b,
677 gs86set_op = 0x30,
678 gstm_op = 0x31,
679 gscvt_ld_op = 0x32,
680 gscvt_ud_op = 0x33,
681 gseflag_op = 0x34,
682 gscam_op = 0x35,
683 gstop_op = 0x36,
684 gssettag_op = 0x37,
685 gssdbbp_op = 0x38
686 };
688 enum gscam_ops {
689 campv_op = 0x0,
690 campi_op = 0x1,
691 camwi_op = 0x2,
692 ramri_op = 0x3
693 };
695 static const char* special2_name[];
697 // special3 family, the opcode is in low 6 bits.
698 enum special3_ops {
699 ext_op = 0x00,
700 dextm_op = 0x01,
701 dextu_op = 0x02,
702 dext_op = 0x03,
703 ins_op = 0x04,
704 dinsm_op = 0x05,
705 dinsu_op = 0x06,
706 dins_op = 0x07,
707 lxx_op = 0x0a, //lwx, lhx, lbux, ldx
708 insv_op = 0x0c,
709 dinsv_op = 0x0d,
710 ar1_op = 0x10, //MIPS DSP
711 cmp1_op = 0x11, //MIPS DSP
712 re1_op = 0x12, //MIPS DSP, re1_ops
713 sh1_op = 0x13, //MIPS DSP
714 ar2_op = 0x14, //MIPS DSP
715 cmp2_op = 0x15, //MIPS DSP
716 re2_op = 0x16, //MIPS DSP, re2_ops
717 sh2_op = 0x17, //MIPS DSP
718 ar3_op = 0x18, //MIPS DSP
719 bshfl_op = 0x20, //seb, seh
720 rdhwr_op = 0x3b
721 };
723 // re1_ops
724 enum re1_ops {
725 absq_s_qb_op = 0x01,
726 repl_qb_op = 0x02,
727 replv_qb_op = 0x03,
728 absq_s_ph_op = 0x09,
729 repl_ph_op = 0x0a,
730 replv_ph_op = 0x0b,
731 absq_s_w_op = 0x11,
732 bitrev_op = 0x1b
733 };
735 // re2_ops
736 enum re2_ops {
737 repl_ob_op = 0x02,
738 replv_ob_op = 0x03,
739 absq_s_qh_op = 0x09,
740 repl_qh_op = 0x0a,
741 replv_qh_op = 0x0b,
742 absq_s_pw_op = 0x11,
743 repl_pw_op = 0x12,
744 replv_pw_op = 0x13
745 };
747 static const char* special3_name[];
749 // lwc2/gs_lwc2 family, the opcode is in low 6 bits.
750 enum gs_lwc2_ops {
751 gslble_op = 0x10,
752 gslbgt_op = 0x11,
753 gslhle_op = 0x12,
754 gslhgt_op = 0x13,
755 gslwle_op = 0x14,
756 gslwgt_op = 0x15,
757 gsldle_op = 0x16,
758 gsldgt_op = 0x17,
759 gslwlec1_op = 0x1c,
760 gslwgtc1_op = 0x1d,
761 gsldlec1_op = 0x1e,
762 gsldgtc1_op = 0x1f,
763 gslq_op = 0x20
764 };
766 static const char* gs_lwc2_name[];
768 // ldc2/gs_ldc2 family, the opcode is in low 3 bits.
769 enum gs_ldc2_ops {
770 gslbx_op = 0x0,
771 gslhx_op = 0x1,
772 gslwx_op = 0x2,
773 gsldx_op = 0x3,
774 gslwxc1_op = 0x6,
775 gsldxc1_op = 0x7
776 };
778 static const char* gs_ldc2_name[];
780 // swc2/gs_swc2 family, the opcode is in low 6 bits.
781 enum gs_swc2_ops {
782 gssble_op = 0x10,
783 gssbgt_op = 0x11,
784 gsshle_op = 0x12,
785 gsshgt_op = 0x13,
786 gsswle_op = 0x14,
787 gsswgt_op = 0x15,
788 gssdle_op = 0x16,
789 gssdgt_op = 0x17,
790 gsswlec1_op = 0x1c,
791 gsswgtc1_op = 0x1d,
792 gssdlec1_op = 0x1e,
793 gssdgtc1_op = 0x1f,
794 gssq_op = 0x20
795 };
797 static const char* gs_swc2_name[];
799 // sdc2/gs_sdc2 family, the opcode is in low 3 bits.
800 enum gs_sdc2_ops {
801 gssbx_op = 0x0,
802 gsshx_op = 0x1,
803 gsswx_op = 0x2,
804 gssdx_op = 0x3,
805 gsswxc1_op = 0x6,
806 gssdxc1_op = 0x7
807 };
809 static const char* gs_sdc2_name[];
811 enum WhichOperand {
812 // input to locate_operand, and format code for relocations
813 imm_operand = 0, // embedded 32-bit|64-bit immediate operand
814 disp32_operand = 1, // embedded 32-bit displacement or address
815 call32_operand = 2, // embedded 32-bit self-relative displacement
816 #ifndef _LP64
817 _WhichOperand_limit = 3
818 #else
819 narrow_oop_operand = 3, // embedded 32-bit immediate narrow oop
820 _WhichOperand_limit = 4
821 #endif
822 };
824 static int opcode(int insn) { return (insn>>26)&0x3f; }
825 static int rs(int insn) { return (insn>>21)&0x1f; }
826 static int rt(int insn) { return (insn>>16)&0x1f; }
827 static int rd(int insn) { return (insn>>11)&0x1f; }
828 static int sa(int insn) { return (insn>>6)&0x1f; }
829 static int special(int insn) { return insn&0x3f; }
830 static int imm_off(int insn) { return (short)low16(insn); }
832 static int low (int x, int l) { return bitfield(x, 0, l); }
833 static int low16(int x) { return low(x, 16); }
834 static int low26(int x) { return low(x, 26); }
836 protected:
837 //help methods for instruction ejection
839 // I-Type (Immediate)
840 // 31 26 25 21 20 16 15 0
841 //| opcode | rs | rt | immediat |
842 //| | | | |
843 // 6 5 5 16
844 static int insn_ORRI(int op, int rs, int rt, int imm) { assert(is_simm16(imm), "not a signed 16-bit int"); return (op<<26) | (rs<<21) | (rt<<16) | low16(imm); }
846 // R-Type (Register)
847 // 31 26 25 21 20 16 15 11 10 6 5 0
848 //| special | rs | rt | rd | 0 | opcode |
849 //| 0 0 0 0 0 0 | | | | 0 0 0 0 0 | |
850 // 6 5 5 5 5 6
851 static int insn_RRRO(int rs, int rt, int rd, int op) { return (rs<<21) | (rt<<16) | (rd<<11) | op; }
852 static int insn_RRSO(int rt, int rd, int sa, int op) { return (rt<<16) | (rd<<11) | (sa<<6) | op; }
853 static int insn_RRCO(int rs, int rt, int code, int op) { return (rs<<21) | (rt<<16) | (code<<6) | op; }
855 static int insn_COP0(int op, int rt, int rd) { return (cop0_op<<26) | (op<<21) | (rt<<16) | (rd<<11); }
856 static int insn_COP1(int op, int rt, int fs) { return (cop1_op<<26) | (op<<21) | (rt<<16) | (fs<<11); }
858 static int insn_F3RO(int fmt, int ft, int fs, int fd, int func) {
859 return (cop1_op<<26) | (fmt<<21) | (ft<<16) | (fs<<11) | (fd<<6) | func;
860 }
861 static int insn_F3ROX(int fmt, int ft, int fs, int fd, int func) {
862 return (cop1x_op<<26) | (fmt<<21) | (ft<<16) | (fs<<11) | (fd<<6) | func;
863 }
865 static int high (int x, int l) { return bitfield(x, 32-l, l); }
866 static int high16(int x) { return high(x, 16); }
867 static int high6 (int x) { return high(x, 6); }
869 //get the offset field of jump/branch instruction
870 int offset(address entry) {
871 assert(is_simm16((entry - pc() - 4) / 4), "change this code");
872 if (!is_simm16((entry - pc() - 4) / 4)) {
873 tty->print_cr("!!! is_simm16: %x", (entry - pc() - 4) / 4);
874 }
875 return (entry - pc() - 4) / 4;
876 }
879 public:
880 using AbstractAssembler::offset;
882 //sign expand with the sign bit is h
883 static int expand(int x, int h) { return -(x & (1<<h)) | x; }
885 // If x is a mask, return the number of one-bit in x.
886 // else return -1.
887 static int is_int_mask(int x);
889 // If x is a mask, return the number of one-bit in x.
890 // else return -1.
891 static int is_jlong_mask(jlong x);
893 // MIPS lui/addiu is both sign extended, so if you wan't to use off32/imm32, you have to use the follow three
894 static int split_low(int x) {
895 return (x & 0xffff);
896 }
898 // Convert 16-bit x to a sign-extended 16-bit integer
899 static int simm16(int x) {
900 assert(x == (x & 0xFFFF), "must be 16-bit only");
901 return (x << 16) >> 16;
902 }
904 static int split_high(int x) {
905 return ( (x >> 16) + ((x & 0x8000) != 0) ) & 0xffff;
906 }
908 static int merge(int low, int high) {
909 return expand(low, 15) + (high<<16);
910 }
912 #ifdef _LP64
913 static intptr_t merge(intptr_t x0, intptr_t x16, intptr_t x32, intptr_t x48) {
914 return (x48 << 48) | (x32 << 32) | (x16 << 16) | x0;
915 }
916 #endif
918 // Test if x is within signed immediate range for nbits.
919 static bool is_simm (int x, int nbits) {
920 assert(0 < nbits && nbits < 32, "out of bounds");
921 const int min = -( ((int)1) << nbits-1 );
922 const int maxplus1 = ( ((int)1) << nbits-1 );
923 return min <= x && x < maxplus1;
924 }
926 static bool is_simm(jlong x, unsigned int nbits) {
927 assert(0 < nbits && nbits < 64, "out of bounds");
928 const jlong min = -( ((jlong)1) << nbits-1 );
929 const jlong maxplus1 = ( ((jlong)1) << nbits-1 );
930 return min <= x && x < maxplus1;
931 }
933 // Test if x is within unsigned immediate range for nbits
934 static bool is_uimm(int x, unsigned int nbits) {
935 assert(0 < nbits && nbits < 32, "out of bounds");
936 const int maxplus1 = ( ((int)1) << nbits );
937 return 0 <= x && x < maxplus1;
938 }
940 static bool is_uimm(jlong x, unsigned int nbits) {
941 assert(0 < nbits && nbits < 64, "out of bounds");
942 const jlong maxplus1 = ( ((jlong)1) << nbits );
943 return 0 <= x && x < maxplus1;
944 }
946 static bool is_simm16(int x) { return is_simm(x, 16); }
947 static bool is_simm16(long x) { return is_simm((jlong)x, (unsigned int)16); }
949 static bool fit_in_jal(address target, address pc) {
950 #ifdef _LP64
951 intptr_t mask = 0xfffffffff0000000;
952 #else
953 intptr_t mask = 0xf0000000;
954 #endif
955 return ((intptr_t)(pc + 4) & mask) == ((intptr_t)target & mask);
956 }
958 bool fit_int_branch(address entry) {
959 return is_simm16(offset(entry));
960 }
962 protected:
963 #ifdef ASSERT
964 #define CHECK_DELAY
965 #endif
966 #ifdef CHECK_DELAY
967 enum Delay_state { no_delay, at_delay_slot, filling_delay_slot } delay_state;
968 #endif
970 public:
971 void assert_not_delayed() {
972 #ifdef CHECK_DELAY
973 assert_not_delayed("next instruction should not be a delay slot");
974 #endif
975 }
977 void assert_not_delayed(const char* msg) {
978 #ifdef CHECK_DELAY
979 //guarantee( delay_state == no_delay, msg );
980 //aoqi_test
981 if(delay_state != no_delay){
982 tty->print_cr("%s:%d, pc: %lx", __func__, __LINE__, pc());
983 }
984 assert(delay_state == no_delay, msg);
985 #endif
986 }
988 protected:
989 // Delay slot helpers
990 // cti is called when emitting control-transfer instruction,
991 // BEFORE doing the emitting.
992 // Only effective when assertion-checking is enabled.
994 // called when emitting cti with a delay slot, AFTER emitting
995 void has_delay_slot() {
996 #ifdef CHECK_DELAY
997 assert_not_delayed("just checking");
998 delay_state = at_delay_slot;
999 #endif
1000 }
1002 public:
1003 Assembler* delayed() {
1004 #ifdef CHECK_DELAY
1005 guarantee( delay_state == at_delay_slot, "delayed instructition is not in delay slot");
1006 delay_state = filling_delay_slot;
1007 #endif
1008 return this;
1009 }
1011 void flush() {
1012 #ifdef CHECK_DELAY
1013 guarantee( delay_state == no_delay, "ending code with a delay slot");
1014 #endif
1015 AbstractAssembler::flush();
1016 }
1018 inline void emit_long(int); // shadows AbstractAssembler::emit_long
1019 inline void emit_data(int x) { emit_long(x); }
1020 inline void emit_data(int, RelocationHolder const&);
1021 inline void emit_data(int, relocInfo::relocType rtype);
1022 inline void check_delay();
1025 // Generic instructions
1026 // Does 32bit or 64bit as needed for the platform. In some sense these
1027 // belong in macro assembler but there is no need for both varieties to exist
1029 #ifndef _LP64
1030 void add(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), add_op)); }
1031 void addi(Register rt, Register rs, int imm) { emit_long(insn_ORRI(addi_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
1032 void addiu(Register rt, Register rs, int imm) { emit_long(insn_ORRI(addiu_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
1033 void addu(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), addu_op)); }
1034 #else
1035 void add(Register rd, Register rs, Register rt) { dadd (rd, rs, rt); }
1036 void add32(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), add_op)); }
1037 void addu32(Register rd, Register rs, Register rt){ emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), addu_op)); }
1038 void addiu32(Register rt, Register rs, int imm) { emit_long(insn_ORRI(addiu_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
1039 void addi(Register rt, Register rs, int imm) { daddi (rt, rs, imm);}
1040 void addiu(Register rt, Register rs, int imm) { daddiu (rt, rs, imm);}
1041 void addu(Register rd, Register rs, Register rt) { daddu (rd, rs, rt); }
1042 #endif
1044 void andr(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), and_op)); }
1045 void andi(Register rt, Register rs, int imm) { emit_long(insn_ORRI(andi_op, (int)rs->encoding(), (int)rt->encoding(), simm16(imm))); }
1047 void beq (Register rs, Register rt, int off) { emit_long(insn_ORRI(beq_op, (int)rs->encoding(), (int)rt->encoding(), off)); has_delay_slot(); }
1048 void beql (Register rs, Register rt, int off) { emit_long(insn_ORRI(beql_op, (int)rs->encoding(), (int)rt->encoding(), off)); has_delay_slot(); }
1049 void bgez (Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bgez_op, off)); has_delay_slot(); }
1050 void bgezal (Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bgezal_op, off)); has_delay_slot(); }
1051 void bgezall(Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bgezall_op, off)); has_delay_slot(); }
1052 void bgezl (Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bgezl_op, off)); has_delay_slot(); }
1053 void bgtz (Register rs, int off) { emit_long(insn_ORRI(bgtz_op, (int)rs->encoding(), 0, off)); has_delay_slot(); }
1054 void bgtzl (Register rs, int off) { emit_long(insn_ORRI(bgtzl_op, (int)rs->encoding(), 0, off)); has_delay_slot(); }
1055 void blez (Register rs, int off) { emit_long(insn_ORRI(blez_op, (int)rs->encoding(), 0, off)); has_delay_slot(); }
1056 void blezl (Register rs, int off) { emit_long(insn_ORRI(blezl_op, (int)rs->encoding(), 0, off)); has_delay_slot(); }
1057 void bltz (Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bltz_op, off)); has_delay_slot(); }
1058 void bltzal (Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bltzal_op, off)); has_delay_slot(); }
1059 void bltzall(Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bltzall_op, off)); has_delay_slot(); }
1060 void bltzl (Register rs, int off) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), bltzl_op, off)); has_delay_slot(); }
1061 void bne (Register rs, Register rt, int off) { emit_long(insn_ORRI(bne_op, (int)rs->encoding(), (int)rt->encoding(), off)); has_delay_slot(); }
1062 void bnel (Register rs, Register rt, int off) { emit_long(insn_ORRI(bnel_op, (int)rs->encoding(), (int)rt->encoding(), off)); has_delay_slot(); }
1063 // two versions of brk:
1064 // the brk(code) version is according to MIPS64 Architecture For Programmers Volume II: The MIPS64 Instruction Set
1065 // the brk(code1, code2) is according to disassembler of hsdis (binutils-2.27)
1066 // both versions work
1067 void brk (int code) { assert(is_uimm(code, 20), "code is 20 bits"); emit_long( (low(code, 20)<<6) | break_op ); }
1068 void brk (int code1, int code2) { assert(is_uimm(code1, 10) && is_uimm(code2, 10), "code is 20 bits"); emit_long( (low(code1, 10)<<16) | (low(code2, 10)<<6) | break_op ); }
1070 void beq (Register rs, Register rt, address entry) { beq(rs, rt, offset(entry)); }
1071 void beql (Register rs, Register rt, address entry) { beql(rs, rt, offset(entry));}
1072 void bgez (Register rs, address entry) { bgez (rs, offset(entry)); }
1073 void bgezal (Register rs, address entry) { bgezal (rs, offset(entry)); }
1074 void bgezall(Register rs, address entry) { bgezall(rs, offset(entry)); }
1075 void bgezl (Register rs, address entry) { bgezl (rs, offset(entry)); }
1076 void bgtz (Register rs, address entry) { bgtz (rs, offset(entry)); }
1077 void bgtzl (Register rs, address entry) { bgtzl (rs, offset(entry)); }
1078 void blez (Register rs, address entry) { blez (rs, offset(entry)); }
1079 void blezl (Register rs, address entry) { blezl (rs, offset(entry)); }
1080 void bltz (Register rs, address entry) { bltz (rs, offset(entry)); }
1081 void bltzal (Register rs, address entry) { bltzal (rs, offset(entry)); }
1082 void bltzall(Register rs, address entry) { bltzall(rs, offset(entry)); }
1083 void bltzl (Register rs, address entry) { bltzl (rs, offset(entry)); }
1084 void bne (Register rs, Register rt, address entry) { bne(rs, rt, offset(entry)); }
1085 void bnel (Register rs, Register rt, address entry) { bnel(rs, rt, offset(entry)); }
1087 void beq (Register rs, Register rt, Label& L) { beq(rs, rt, target(L)); }
1088 void beql (Register rs, Register rt, Label& L) { beql(rs, rt, target(L)); }
1089 void bgez (Register rs, Label& L){ bgez (rs, target(L)); }
1090 void bgezal (Register rs, Label& L){ bgezal (rs, target(L)); }
1091 void bgezall(Register rs, Label& L){ bgezall(rs, target(L)); }
1092 void bgezl (Register rs, Label& L){ bgezl (rs, target(L)); }
1093 void bgtz (Register rs, Label& L){ bgtz (rs, target(L)); }
1094 void bgtzl (Register rs, Label& L){ bgtzl (rs, target(L)); }
1095 void blez (Register rs, Label& L){ blez (rs, target(L)); }
1096 void blezl (Register rs, Label& L){ blezl (rs, target(L)); }
1097 void bltz (Register rs, Label& L){ bltz (rs, target(L)); }
1098 void bltzal (Register rs, Label& L){ bltzal (rs, target(L)); }
1099 void bltzall(Register rs, Label& L){ bltzall(rs, target(L)); }
1100 void bltzl (Register rs, Label& L){ bltzl (rs, target(L)); }
1101 void bne (Register rs, Register rt, Label& L){ bne(rs, rt, target(L)); }
1102 void bnel (Register rs, Register rt, Label& L){ bnel(rs, rt, target(L)); }
1104 void dadd (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), dadd_op)); }
1105 void daddi (Register rt, Register rs, int imm) { emit_long(insn_ORRI(daddi_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
1106 void daddiu(Register rt, Register rs, int imm) { emit_long(insn_ORRI(daddiu_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
1107 void daddu (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), daddu_op)); }
1108 void ddiv (Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, ddiv_op)); }
1109 void ddivu (Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, ddivu_op)); }
1111 void movz (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), movz_op)); }
1112 void movn (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), movn_op)); }
1114 void movt (Register rd, Register rs) { emit_long(((int)rs->encoding() << 21) | (1 << 16) | ((int)rd->encoding() << 11) | movci_op); }
1115 void movf (Register rd, Register rs) { emit_long(((int)rs->encoding() << 21) | ((int)rd->encoding() << 11) | movci_op); }
1117 enum bshfl_ops {
1118 seb_op = 0x10,
1119 seh_op = 0x18
1120 };
1121 void seb (Register rd, Register rt) { emit_long((special3_op << 26) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | (seb_op << 6) | bshfl_op); }
1122 void seh (Register rd, Register rt) { emit_long((special3_op << 26) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | (seh_op << 6) | bshfl_op); }
1124 void ext (Register rt, Register rs, int pos, int size) {
1125 guarantee((0 <= pos) && (pos < 32), "pos must be in [0, 32)");
1126 guarantee((0 < size) && (size <= 32), "size must be in (0, 32]");
1127 guarantee((0 < pos + size) && (pos + size <= 32), "pos + size must be in (0, 32]");
1129 int lsb = pos;
1130 int msbd = size - 1;
1132 emit_long((special3_op << 26) | ((int)rs->encoding() << 21) | ((int)rt->encoding() << 16) | (msbd << 11) | (lsb << 6) | ext_op);
1133 }
1135 void dext (Register rt, Register rs, int pos, int size) {
1136 guarantee((0 <= pos) && (pos < 32), "pos must be in [0, 32)");
1137 guarantee((0 < size) && (size <= 32), "size must be in (0, 32]");
1138 guarantee((0 < pos + size) && (pos + size <= 63), "pos + size must be in (0, 63]");
1140 int lsb = pos;
1141 int msbd = size - 1;
1143 emit_long((special3_op << 26) | ((int)rs->encoding() << 21) | ((int)rt->encoding() << 16) | (msbd << 11) | (lsb << 6) | dext_op);
1144 }
1146 void rotr (Register rd, Register rt, int sa) {
1147 emit_long((special_op << 26) | (1 << 21) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | (low(sa, 5) << 6) | srl_op);
1148 }
1150 void drotr (Register rd, Register rt, int sa) {
1151 emit_long((special_op << 26) | (1 << 21) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | (low(sa, 5) << 6) | dsrl_op);
1152 }
1154 void drotr32 (Register rd, Register rt, int sa) {
1155 emit_long((special_op << 26) | (1 << 21) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | (low(sa, 5) << 6) | dsrl32_op);
1156 }
1158 void rotrv (Register rd, Register rt, Register rs) {
1159 emit_long((special_op << 26) | ((int)rs->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | (1 << 6) | srlv_op);
1160 }
1162 void drotrv (Register rd, Register rt, Register rs) {
1163 emit_long((special_op << 26) | ((int)rs->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | (1 << 6) | dsrlv_op);
1164 }
1166 void div (Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, div_op)); }
1167 void divu (Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, divu_op)); }
1168 void dmult (Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, dmult_op)); }
1169 void dmultu(Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, dmultu_op)); }
1170 void dsll (Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), low(sa, 5), dsll_op)); }
1171 void dsllv (Register rd, Register rt, Register rs) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), dsllv_op)); }
1172 void dsll32(Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), low(sa, 5), dsll32_op)); }
1173 void dsra (Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), low(sa, 5), dsra_op)); }
1174 void dsrav (Register rd, Register rt, Register rs) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), dsrav_op)); }
1175 void dsra32(Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), low(sa, 5), dsra32_op)); }
1176 void dsrl (Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), low(sa, 5), dsrl_op)); }
1177 void dsrlv (Register rd, Register rt, Register rs) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), dsrlv_op)); }
1178 void dsrl32(Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), low(sa, 5), dsrl32_op)); }
1179 void dsub (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), dsub_op)); }
1180 void dsubu (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), dsubu_op)); }
1182 void b(int off) { beq(R0, R0, off); }
1183 void b(address entry) { b(offset(entry)); }
1184 void b(Label& L) { b(target(L)); }
1186 void j(address entry);
1187 void jal(address entry);
1189 void jalr(Register rd, Register rs) { emit_long( ((int)rs->encoding()<<21) | ((int)rd->encoding()<<11) | jalr_op); has_delay_slot(); }
1190 void jalr(Register rs) { jalr(RA, rs); }
1191 void jalr() { jalr(T9); }
1193 void jr(Register rs) { emit_long(((int)rs->encoding()<<21) | jr_op); has_delay_slot(); }
1195 void lb (Register rt, Register base, int off) { emit_long(insn_ORRI(lb_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1196 void lbu(Register rt, Register base, int off) { emit_long(insn_ORRI(lbu_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1197 void ld (Register rt, Register base, int off) { emit_long(insn_ORRI(ld_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1198 void ldl(Register rt, Register base, int off) { emit_long(insn_ORRI(ldl_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1199 void ldr(Register rt, Register base, int off) { emit_long(insn_ORRI(ldr_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1200 void lh (Register rt, Register base, int off) { emit_long(insn_ORRI(lh_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1201 void lhu(Register rt, Register base, int off) { emit_long(insn_ORRI(lhu_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1202 void ll (Register rt, Register base, int off) { emit_long(insn_ORRI(ll_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1203 void lld(Register rt, Register base, int off) { emit_long(insn_ORRI(lld_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1204 void lui(Register rt, int imm) { emit_long(insn_ORRI(lui_op, 0, (int)rt->encoding(), simm16(imm))); }
1205 void lw (Register rt, Register base, int off) { emit_long(insn_ORRI(lw_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1206 void lwl(Register rt, Register base, int off) { emit_long(insn_ORRI(lwl_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1207 void lwr(Register rt, Register base, int off) { emit_long(insn_ORRI(lwr_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1208 void lwu(Register rt, Register base, int off) { emit_long(insn_ORRI(lwu_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1210 void lb (Register rt, Address src);
1211 void lbu(Register rt, Address src);
1212 void ld (Register rt, Address src);
1213 void ldl(Register rt, Address src);
1214 void ldr(Register rt, Address src);
1215 void lh (Register rt, Address src);
1216 void lhu(Register rt, Address src);
1217 void ll (Register rt, Address src);
1218 void lld(Register rt, Address src);
1219 void lw (Register rt, Address src);
1220 void lwl(Register rt, Address src);
1221 void lwr(Register rt, Address src);
1222 void lwu(Register rt, Address src);
1223 void lea(Register rt, Address src);
1224 void pref(int hint, Register base, int off) { emit_long(insn_ORRI(pref_op, (int)base->encoding(), low(hint, 5), low(off, 16))); }
1226 void mfhi (Register rd) { emit_long( ((int)rd->encoding()<<11) | mfhi_op ); }
1227 void mflo (Register rd) { emit_long( ((int)rd->encoding()<<11) | mflo_op ); }
1228 void mthi (Register rs) { emit_long( ((int)rs->encoding()<<21) | mthi_op ); }
1229 void mtlo (Register rs) { emit_long( ((int)rs->encoding()<<21) | mtlo_op ); }
1231 void mult (Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, mult_op)); }
1232 void multu(Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), 0, multu_op)); }
1234 void nor(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), nor_op)); }
1236 void orr(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), or_op)); }
1237 void ori(Register rt, Register rs, int imm) { emit_long(insn_ORRI(ori_op, (int)rs->encoding(), (int)rt->encoding(), simm16(imm))); }
1239 void sb (Register rt, Register base, int off) { emit_long(insn_ORRI(sb_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1240 void sc (Register rt, Register base, int off) { emit_long(insn_ORRI(sc_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1241 void scd (Register rt, Register base, int off) { emit_long(insn_ORRI(scd_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1242 void sd (Register rt, Register base, int off) { emit_long(insn_ORRI(sd_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1243 void sdl (Register rt, Register base, int off) { emit_long(insn_ORRI(sdl_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1244 void sdr (Register rt, Register base, int off) { emit_long(insn_ORRI(sdr_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1245 void sh (Register rt, Register base, int off) { emit_long(insn_ORRI(sh_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1246 void sll (Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), low(sa, 5), sll_op)); }
1247 void sllv (Register rd, Register rt, Register rs) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), sllv_op)); }
1248 void slt (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), slt_op)); }
1249 void slti (Register rt, Register rs, int imm) { emit_long(insn_ORRI(slti_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
1250 void sltiu(Register rt, Register rs, int imm) { emit_long(insn_ORRI(sltiu_op, (int)rs->encoding(), (int)rt->encoding(), imm)); }
1251 void sltu (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), sltu_op)); }
1252 void sra (Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), low(sa, 5), sra_op)); }
1253 void srav (Register rd, Register rt, Register rs) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), srav_op)); }
1254 void srl (Register rd, Register rt , int sa) { emit_long(insn_RRSO((int)rt->encoding(), (int)rd->encoding(), low(sa, 5), srl_op)); }
1255 void srlv (Register rd, Register rt, Register rs) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), srlv_op)); }
1257 #ifndef _LP64
1258 void sub (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), sub_op)); }
1259 void subu (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), subu_op)); }
1260 #else
1261 void sub (Register rd, Register rs, Register rt) { dsub (rd, rs, rt); }
1262 void subu (Register rd, Register rs, Register rt) { dsubu (rd, rs, rt); }
1263 void subu32 (Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), subu_op)); }
1264 #endif
1265 void sw (Register rt, Register base, int off) { emit_long(insn_ORRI(sw_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1266 void swl (Register rt, Register base, int off) { emit_long(insn_ORRI(swl_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1267 void swr (Register rt, Register base, int off) { emit_long(insn_ORRI(swr_op, (int)base->encoding(), (int)rt->encoding(), off)); }
1268 void sync () { emit_long(sync_op); }
1269 void syscall(int code) { emit_long( (code<<6) | syscall_op ); }
1271 void sb(Register rt, Address dst);
1272 void sc(Register rt, Address dst);
1273 void scd(Register rt, Address dst);
1274 void sd(Register rt, Address dst);
1275 void sdl(Register rt, Address dst);
1276 void sdr(Register rt, Address dst);
1277 void sh(Register rt, Address dst);
1278 void sw(Register rt, Address dst);
1279 void swl(Register rt, Address dst);
1280 void swr(Register rt, Address dst);
1282 void teq (Register rs, Register rt, int code) { emit_long(insn_RRCO((int)rs->encoding(), (int)rt->encoding(), code, teq_op)); }
1283 void teqi (Register rs, int imm) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), teqi_op, imm)); }
1284 void tge (Register rs, Register rt, int code) { emit_long(insn_RRCO((int)rs->encoding(), (int)rt->encoding(), code, tge_op)); }
1285 void tgei (Register rs, int imm) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), tgei_op, imm)); }
1286 void tgeiu(Register rs, int imm) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), tgeiu_op, imm)); }
1287 void tgeu (Register rs, Register rt, int code) { emit_long(insn_RRCO((int)rs->encoding(), (int)rt->encoding(), code, tgeu_op)); }
1288 void tlt (Register rs, Register rt, int code) { emit_long(insn_RRCO((int)rs->encoding(), (int)rt->encoding(), code, tlt_op)); }
1289 void tlti (Register rs, int imm) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), tlti_op, imm)); }
1290 void tltiu(Register rs, int imm) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), tltiu_op, imm)); }
1291 void tltu (Register rs, Register rt, int code) { emit_long(insn_RRCO((int)rs->encoding(), (int)rt->encoding(), code, tltu_op)); }
1292 void tne (Register rs, Register rt, int code) { emit_long(insn_RRCO((int)rs->encoding(), (int)rt->encoding(), code, tne_op)); }
1293 void tnei (Register rs, int imm) { emit_long(insn_ORRI(regimm_op, (int)rs->encoding(), tnei_op, imm)); }
1295 void xorr(Register rd, Register rs, Register rt) { emit_long(insn_RRRO((int)rs->encoding(), (int)rt->encoding(), (int)rd->encoding(), xor_op)); }
1296 void xori(Register rt, Register rs, int imm) { emit_long(insn_ORRI(xori_op, (int)rs->encoding(), (int)rt->encoding(), simm16(imm))); }
1298 void nop() { emit_long(0); }
1302 void ldc1(FloatRegister ft, Register base, int off) { emit_long(insn_ORRI(ldc1_op, (int)base->encoding(), (int)ft->encoding(), off)); }
1303 void lwc1(FloatRegister ft, Register base, int off) { emit_long(insn_ORRI(lwc1_op, (int)base->encoding(), (int)ft->encoding(), off)); }
1304 void ldc1(FloatRegister ft, Address src);
1305 void lwc1(FloatRegister ft, Address src);
1307 //COP0
1308 void mfc0 (Register rt, Register rd) { emit_long(insn_COP0( mfc0_op, (int)rt->encoding(), (int)rd->encoding())); }
1309 void dmfc0 (Register rt, FloatRegister rd) { emit_long(insn_COP0(dmfc0_op, (int)rt->encoding(), (int)rd->encoding())); }
1310 // MFGC0, DMFGC0, MTGC0, DMTGC0 not implemented yet
1311 void mtc0 (Register rt, Register rd) { emit_long(insn_COP0( mtc0_op, (int)rt->encoding(), (int)rd->encoding())); }
1312 void dmtc0 (Register rt, FloatRegister rd) { emit_long(insn_COP0(dmtc0_op, (int)rt->encoding(), (int)rd->encoding())); }
1313 //COP0 end
1316 //COP1
1317 void mfc1 (Register rt, FloatRegister fs) { emit_long(insn_COP1 (mfc1_op, (int)rt->encoding(), (int)fs->encoding())); }
1318 void dmfc1(Register rt, FloatRegister fs) { emit_long(insn_COP1(dmfc1_op, (int)rt->encoding(), (int)fs->encoding())); }
1319 void cfc1 (Register rt, int fs) { emit_long(insn_COP1( cfc1_op, (int)rt->encoding(), fs)); }
1320 void mfhc1(Register rt, int fs) { emit_long(insn_COP1(mfhc1_op, (int)rt->encoding(), fs)); }
1321 void mtc1 (Register rt, FloatRegister fs) { emit_long(insn_COP1( mtc1_op, (int)rt->encoding(), (int)fs->encoding())); }
1322 void dmtc1(Register rt, FloatRegister fs) { emit_long(insn_COP1(dmtc1_op, (int)rt->encoding(), (int)fs->encoding())); }
1323 void ctc1 (Register rt, FloatRegister fs) { emit_long(insn_COP1( ctc1_op, (int)rt->encoding(), (int)fs->encoding())); }
1324 void ctc1 (Register rt, int fs) { emit_long(insn_COP1(ctc1_op, (int)rt->encoding(), fs)); }
1325 void mthc1(Register rt, int fs) { emit_long(insn_COP1(mthc1_op, (int)rt->encoding(), fs)); }
1327 void bc1f (int off) { emit_long(insn_ORRI(cop1_op, bc1f_op, bcf_op, off)); has_delay_slot(); }
1328 void bc1fl(int off) { emit_long(insn_ORRI(cop1_op, bc1f_op, bcfl_op, off)); has_delay_slot(); }
1329 void bc1t (int off) { emit_long(insn_ORRI(cop1_op, bc1f_op, bct_op, off)); has_delay_slot(); }
1330 void bc1tl(int off) { emit_long(insn_ORRI(cop1_op, bc1f_op, bctl_op, off)); has_delay_slot(); }
1332 void bc1f (address entry) { bc1f(offset(entry)); }
1333 void bc1fl(address entry) { bc1fl(offset(entry)); }
1334 void bc1t (address entry) { bc1t(offset(entry)); }
1335 void bc1tl(address entry) { bc1tl(offset(entry)); }
1337 void bc1f (Label& L) { bc1f(target(L)); }
1338 void bc1fl(Label& L) { bc1fl(target(L)); }
1339 void bc1t (Label& L) { bc1t(target(L)); }
1340 void bc1tl(Label& L) { bc1tl(target(L)); }
1342 //R0->encoding() is 0; INSN_SINGLE is enclosed by {} for ctags.
1343 #define INSN_SINGLE(r1, r2, r3, op) \
1344 { emit_long(insn_F3RO(single_fmt, (int)r1->encoding(), (int)r2->encoding(), (int)r3->encoding(), op));}
1345 void add_s (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, fd, fadd_op)}
1346 void sub_s (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, fd, fsub_op)}
1347 void mul_s (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, fd, fmul_op)}
1348 void div_s (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, fd, fdiv_op)}
1349 void sqrt_s (FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, fsqrt_op)}
1350 void abs_s (FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, fabs_op)}
1351 void mov_s (FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, fmov_op)}
1352 void neg_s (FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, fneg_op)}
1353 void round_l_s(FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, froundl_op)}
1354 void trunc_l_s(FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, ftruncl_op)}
1355 void ceil_l_s (FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, fceill_op)}
1356 void floor_l_s(FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, ffloorl_op)}
1357 void round_w_s(FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, froundw_op)}
1358 void trunc_w_s(FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, ftruncw_op)}
1359 void ceil_w_s (FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, fceilw_op)}
1360 void floor_w_s(FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, ffloorw_op)}
1361 //null
1362 void movf_s(FloatRegister fs, FloatRegister fd, int cc = 0) {
1363 assert(cc >= 0 && cc <= 7, "cc is 3 bits");
1364 emit_long((cop1_op<<26) | (single_fmt<<21) | (cc<<18) | ((int)fs->encoding()<<11) | ((int)fd->encoding()<<6) | movf_f_op );}
1365 void movt_s(FloatRegister fs, FloatRegister fd, int cc = 0) {
1366 assert(cc >= 0 && cc <= 7, "cc is 3 bits");
1367 emit_long((cop1_op<<26) | (single_fmt<<21) | (cc<<18) | 1<<16 | ((int)fs->encoding()<<11) | ((int)fd->encoding()<<6) | movf_f_op );}
1368 void movz_s (FloatRegister fd, FloatRegister fs, Register rt) {INSN_SINGLE(rt, fs, fd, movz_f_op)}
1369 void movn_s (FloatRegister fd, FloatRegister fs, Register rt) {INSN_SINGLE(rt, fs, fd, movn_f_op)}
1370 //null
1371 void recip_s (FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, frecip_op)}
1372 void rsqrt_s (FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, frsqrt_op)}
1373 //null
1374 void cvt_d_s (FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, fcvtd_op)}
1375 //null
1376 void cvt_w_s (FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, fcvtw_op)}
1377 void cvt_l_s (FloatRegister fd, FloatRegister fs) {INSN_SINGLE(R0, fs, fd, fcvtl_op)}
1378 void cvt_ps_s(FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, fd, fcvtps_op)}
1379 //null
1380 void c_f_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, f_cond)}
1381 void c_un_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, un_cond)}
1382 void c_eq_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, eq_cond)}
1383 void c_ueq_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, ueq_cond)}
1384 void c_olt_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, olt_cond)}
1385 void c_ult_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, ult_cond)}
1386 void c_ole_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, ole_cond)}
1387 void c_ule_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, ule_cond)}
1388 void c_sf_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, sf_cond)}
1389 void c_ngle_s(FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, ngle_cond)}
1390 void c_seq_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, seq_cond)}
1391 void c_ngl_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, ngl_cond)}
1392 void c_lt_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, lt_cond)}
1393 void c_nge_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, nge_cond)}
1394 void c_le_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, le_cond)}
1395 void c_ngt_s (FloatRegister fs, FloatRegister ft) {INSN_SINGLE(ft, fs, R0, ngt_cond)}
1397 #undef INSN_SINGLE
1400 //R0->encoding() is 0; INSN_DOUBLE is enclosed by {} for ctags.
1401 #define INSN_DOUBLE(r1, r2, r3, op) \
1402 { emit_long(insn_F3RO(double_fmt, (int)r1->encoding(), (int)r2->encoding(), (int)r3->encoding(), op));}
1404 void add_d (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, fd, fadd_op)}
1405 void sub_d (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, fd, fsub_op)}
1406 void mul_d (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, fd, fmul_op)}
1407 void div_d (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, fd, fdiv_op)}
1408 void sqrt_d (FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, fsqrt_op)}
1409 void abs_d (FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, fabs_op)}
1410 void mov_d (FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, fmov_op)}
1411 void neg_d (FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, fneg_op)}
1412 void round_l_d(FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, froundl_op)}
1413 void trunc_l_d(FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, ftruncl_op)}
1414 void ceil_l_d (FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, fceill_op)}
1415 void floor_l_d(FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, ffloorl_op)}
1416 void round_w_d(FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, froundw_op)}
1417 void trunc_w_d(FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, ftruncw_op)}
1418 void ceil_w_d (FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, fceilw_op)}
1419 void floor_w_d(FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, ffloorw_op)}
1420 //null
1421 void movf_d(FloatRegister fs, FloatRegister fd, int cc = 0) {
1422 assert(cc >= 0 && cc <= 7, "cc is 3 bits");
1423 emit_long((cop1_op<<26) | (double_fmt<<21) | (cc<<18) | ((int)fs->encoding()<<11) | ((int)fd->encoding()<<6) | movf_f_op );}
1424 void movt_d(FloatRegister fs, FloatRegister fd, int cc = 0) {
1425 assert(cc >= 0 && cc <= 7, "cc is 3 bits");
1426 emit_long((cop1_op<<26) | (double_fmt<<21) | (cc<<18) | 1<<16 | ((int)fs->encoding()<<11) | ((int)fd->encoding()<<6) | movf_f_op );}
1427 void movz_d (FloatRegister fd, FloatRegister fs, Register rt) {INSN_DOUBLE(rt, fs, fd, movz_f_op)}
1428 void movn_d (FloatRegister fd, FloatRegister fs, Register rt) {INSN_DOUBLE(rt, fs, fd, movn_f_op)}
1429 //null
1430 void recip_d (FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, frecip_op)}
1431 void rsqrt_d (FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, frsqrt_op)}
1432 //null
1433 void cvt_s_d (FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, fcvts_op)}
1434 void cvt_l_d (FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, fcvtl_op)}
1435 //null
1436 void cvt_w_d (FloatRegister fd, FloatRegister fs) {INSN_DOUBLE(R0, fs, fd, fcvtw_op)}
1437 //null
1438 void c_f_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, f_cond)}
1439 void c_un_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, un_cond)}
1440 void c_eq_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, eq_cond)}
1441 void c_ueq_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, ueq_cond)}
1442 void c_olt_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, olt_cond)}
1443 void c_ult_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, ult_cond)}
1444 void c_ole_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, ole_cond)}
1445 void c_ule_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, ule_cond)}
1446 void c_sf_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, sf_cond)}
1447 void c_ngle_d(FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, ngle_cond)}
1448 void c_seq_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, seq_cond)}
1449 void c_ngl_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, ngl_cond)}
1450 void c_lt_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, lt_cond)}
1451 void c_nge_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, nge_cond)}
1452 void c_le_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, le_cond)}
1453 void c_ngt_d (FloatRegister fs, FloatRegister ft) {INSN_DOUBLE(ft, fs, R0, ngt_cond)}
1455 #undef INSN_DOUBLE
1458 //null
1459 void cvt_s_w(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(word_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvts_op)); }
1460 void cvt_d_w(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(word_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvtd_op)); }
1461 //null
1462 void cvt_s_l(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(long_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvts_op)); }
1463 void cvt_d_l(FloatRegister fd, FloatRegister fs) { emit_long(insn_F3RO(long_fmt, 0, (int)fs->encoding(), (int)fd->encoding(), fcvtd_op)); }
1464 //null
1467 //R0->encoding() is 0; INSN_PS is enclosed by {} for ctags.
1468 #define INSN_PS(r1, r2, r3, op) \
1469 { emit_long(insn_F3RO(ps_fmt, (int)r1->encoding(), (int)r2->encoding(), (int)r3->encoding(), op));}
1471 void add_ps (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, fd, fadd_op)}
1472 void sub_ps (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, fd, fsub_op)}
1473 void mul_ps (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, fd, fmul_op)}
1474 //null
1475 void abs_ps (FloatRegister fd, FloatRegister fs) {INSN_PS(R0, fs, fd, fabs_op)}
1476 void mov_ps (FloatRegister fd, FloatRegister fs) {INSN_PS(R0, fs, fd, fmov_op)}
1477 void neg_ps (FloatRegister fd, FloatRegister fs) {INSN_PS(R0, fs, fd, fneg_op)}
1478 //null
1479 //void movf_ps(FloatRegister rd, FloatRegister rs, FPConditionCode cc) { unimplemented(" movf_ps")}
1480 //void movt_ps(FloatRegister rd, FloatRegister rs, FPConditionCode cc) { unimplemented(" movt_ps") }
1481 void movz_ps (FloatRegister fd, FloatRegister fs, Register rt) {INSN_PS(rt, fs, fd, movz_f_op)}
1482 void movn_ps (FloatRegister fd, FloatRegister fs, Register rt) {INSN_PS(rt, fs, fd, movn_f_op)}
1483 //null
1484 void cvt_s_pu (FloatRegister fd, FloatRegister fs) {INSN_PS(R0, fs, fd, fcvts_op)}
1485 //null
1486 void cvt_s_pl (FloatRegister fd, FloatRegister fs) {INSN_PS(R0, fs, fd, fcvtspl_op)}
1487 //null
1488 void pll_ps (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, fd, fpll_op)}
1489 void plu_ps (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, fd, fplu_op)}
1490 void pul_ps (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, fd, fpul_op)}
1491 void puu_ps (FloatRegister fd, FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, fd, fpuu_op)}
1492 void c_f_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, f_cond)}
1493 void c_un_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, un_cond)}
1494 void c_eq_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, eq_cond)}
1495 void c_ueq_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, ueq_cond)}
1496 void c_olt_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, olt_cond)}
1497 void c_ult_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, ult_cond)}
1498 void c_ole_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, ole_cond)}
1499 void c_ule_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, ule_cond)}
1500 void c_sf_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, sf_cond)}
1501 void c_ngle_ps(FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, ngle_cond)}
1502 void c_seq_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, seq_cond)}
1503 void c_ngl_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, ngl_cond)}
1504 void c_lt_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, lt_cond)}
1505 void c_nge_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, nge_cond)}
1506 void c_le_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, le_cond)}
1507 void c_ngt_ps (FloatRegister fs, FloatRegister ft) {INSN_PS(ft, fs, R0, ngt_cond)}
1508 //null
1509 #undef INSN_PS
1510 //COP1 end
1513 //COP1X
1514 //R0->encoding() is 0; INSN_SINGLE is enclosed by {} for ctags.
1515 #define INSN_COP1X(r0, r1, r2, r3, op) \
1516 { emit_long(insn_F3ROX((int)r0->encoding(), (int)r1->encoding(), (int)r2->encoding(), (int)r3->encoding(), op));}
1517 void madd_s(FloatRegister fd, FloatRegister fr, FloatRegister fs, FloatRegister ft) {INSN_COP1X(fr, ft, fs, fd, madd_s_op) }
1518 void madd_d(FloatRegister fd, FloatRegister fr, FloatRegister fs, FloatRegister ft) {INSN_COP1X(fr, ft, fs, fd, madd_d_op) }
1519 void madd_ps(FloatRegister fd, FloatRegister fr, FloatRegister fs, FloatRegister ft){INSN_COP1X(fr, ft, fs, fd, madd_ps_op) }
1520 void msub_s(FloatRegister fd, FloatRegister fr, FloatRegister fs, FloatRegister ft) {INSN_COP1X(fr, ft, fs, fd, msub_s_op) }
1521 void msub_d(FloatRegister fd, FloatRegister fr, FloatRegister fs, FloatRegister ft) {INSN_COP1X(fr, ft, fs, fd, msub_d_op) }
1522 void msub_ps(FloatRegister fd, FloatRegister fr, FloatRegister fs, FloatRegister ft){INSN_COP1X(fr, ft, fs, fd, msub_ps_op) }
1523 void nmadd_s(FloatRegister fd, FloatRegister fr, FloatRegister fs, FloatRegister ft) {INSN_COP1X(fr, ft, fs, fd, nmadd_s_op) }
1524 void nmadd_d(FloatRegister fd, FloatRegister fr, FloatRegister fs, FloatRegister ft) {INSN_COP1X(fr, ft, fs, fd, nmadd_d_op) }
1525 void nmadd_ps(FloatRegister fd, FloatRegister fr, FloatRegister fs, FloatRegister ft){INSN_COP1X(fr, ft, fs, fd, nmadd_ps_op) }
1526 void nmsub_s(FloatRegister fd, FloatRegister fr, FloatRegister fs, FloatRegister ft) {INSN_COP1X(fr, ft, fs, fd, nmsub_s_op) }
1527 void nmsub_d(FloatRegister fd, FloatRegister fr, FloatRegister fs, FloatRegister ft) {INSN_COP1X(fr, ft, fs, fd, nmsub_d_op) }
1528 void nmsub_ps(FloatRegister fd, FloatRegister fr, FloatRegister fs, FloatRegister ft){INSN_COP1X(fr, ft, fs, fd, nmsub_ps_op) }
1529 #undef INSN_COP1X
1530 //COP1X end
1532 //SPECIAL2
1533 //R0->encoding() is 0; INSN_PS is enclosed by {} for ctags.
1534 #define INSN_S2(op) \
1535 { emit_long((special2_op << 26) | ((int)rs->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | op);}
1537 void madd (Register rs, Register rt) { emit_long((special2_op << 26) | ((int)rs->encoding() << 21) | ((int)rt->encoding() << 16) | madd_op); }
1538 void maddu (Register rs, Register rt) { emit_long((special2_op << 26) | ((int)rs->encoding() << 21) | ((int)rt->encoding() << 16) | maddu_op); }
1539 void mul (Register rd, Register rs, Register rt) { INSN_S2(mul_op) }
1540 void gsandn (Register rd, Register rs, Register rt) { INSN_S2((0x12 << 6) | gs0x03_op) }
1541 void msub (Register rs, Register rt) { emit_long((special2_op << 26) | ((int)rs->encoding() << 21) | ((int)rt->encoding() << 16) | msub_op); }
1542 void msubu (Register rs, Register rt) { emit_long((special2_op << 26) | ((int)rs->encoding() << 21) | ((int)rt->encoding() << 16) | msubu_op); }
1543 void gsorn (Register rd, Register rs, Register rt) { INSN_S2((0x12 << 6) | gs0x06_op) }
1545 void gsmult (Register rd, Register rs, Register rt) { INSN_S2(gsmult_op) }
1546 void gsdmult (Register rd, Register rs, Register rt) { INSN_S2(gsdmult_op) }
1547 void gsmultu (Register rd, Register rs, Register rt) { INSN_S2(gsmultu_op) }
1548 void gsdmultu(Register rd, Register rs, Register rt) { INSN_S2(gsdmultu_op)}
1549 void gsdiv (Register rd, Register rs, Register rt) { INSN_S2(gsdiv_op) }
1550 void gsddiv (Register rd, Register rs, Register rt) { INSN_S2(gsddiv_op) }
1551 void gsdivu (Register rd, Register rs, Register rt) { INSN_S2(gsdivu_op) }
1552 void gsddivu (Register rd, Register rs, Register rt) { INSN_S2(gsddivu_op) }
1553 void gsmod (Register rd, Register rs, Register rt) { INSN_S2(gsmod_op) }
1554 void gsdmod (Register rd, Register rs, Register rt) { INSN_S2(gsdmod_op) }
1555 void gsmodu (Register rd, Register rs, Register rt) { INSN_S2(gsmodu_op) }
1556 void gsdmodu (Register rd, Register rs, Register rt) { INSN_S2(gsdmodu_op) }
1557 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); }
1558 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); }
1559 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); }
1560 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); }
1561 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); }
1562 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); }
1563 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); }
1564 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); }
1566 #undef INSN_S2
1568 //SPECIAL3
1569 /*
1570 // FIXME
1571 #define is_0_to_32(a, b) \
1572 assert (a >= 0, " just a check"); \
1573 assert (a <= 0, " just a check"); \
1574 assert (b >= 0, " just a check"); \
1575 assert (b <= 0, " just a check"); \
1576 assert (a+b >= 0, " just a check"); \
1577 assert (a+b <= 0, " just a check");
1578 */
1579 #define is_0_to_32(a, b)
1581 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); }
1582 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); }
1583 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); }
1584 void dins (Register rt, Register rs, int pos, int size) {
1585 guarantee((0 <= pos) && (pos < 32), "pos must be in [0, 32)");
1586 guarantee((0 < size) && (size <= 32), "size must be in (0, 32]");
1587 guarantee((0 < pos + size) && (pos + size <= 32), "pos + size must be in (0, 32]");
1589 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);
1590 }
1592 void repl_qb (Register rd, int const8) { assert(VM_Version::supports_dsp(), ""); emit_long((special3_op << 26) | (low(const8, 8) << 16) | ((int)rd->encoding() << 11) | repl_qb_op << 6 | re1_op); }
1593 void replv_qb(Register rd, Register rt) { assert(VM_Version::supports_dsp(), ""); emit_long((special3_op << 26) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | replv_qb_op << 6 | re1_op ); }
1594 void repl_ph (Register rd, int const10) { assert(VM_Version::supports_dsp(), ""); emit_long((special3_op << 26) | (low(const10, 10) << 16) | ((int)rd->encoding() << 11) | repl_ph_op << 6 | re1_op); }
1595 void replv_ph(Register rd, Register rt) { assert(VM_Version::supports_dsp(), ""); emit_long((special3_op << 26) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | replv_ph_op << 6 | re1_op ); }
1597 void repl_ob (Register rd, int const8) { assert(VM_Version::supports_dsp(), ""); emit_long((special3_op << 26) | (low(const8, 8) << 16) | ((int)rd->encoding() << 11) | repl_ob_op << 6 | re2_op); }
1598 void replv_ob(Register rd, Register rt) { assert(VM_Version::supports_dsp(), ""); emit_long((special3_op << 26) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | replv_ob_op << 6 | re2_op ); }
1599 void repl_qh (Register rd, int const10) { assert(VM_Version::supports_dsp(), ""); emit_long((special3_op << 26) | (low(const10, 10) << 16) | ((int)rd->encoding() << 11) | repl_qh_op << 6 | re2_op); }
1600 void replv_qh(Register rd, Register rt) { assert(VM_Version::supports_dsp(), ""); emit_long((special3_op << 26) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | replv_qh_op << 6 | re2_op ); }
1601 void repl_pw (Register rd, int const10) { assert(VM_Version::supports_dsp(), ""); emit_long((special3_op << 26) | (low(const10, 10) << 16) | ((int)rd->encoding() << 11) | repl_pw_op << 6 | re2_op); }
1602 void replv_pw(Register rd, Register rt) { assert(VM_Version::supports_dsp(), ""); emit_long((special3_op << 26) | ((int)rt->encoding() << 16) | ((int)rd->encoding() << 11) | replv_pw_op << 6 | re2_op ); }
1604 void sdc1(FloatRegister ft, Register base, int off) { emit_long(insn_ORRI(sdc1_op, (int)base->encoding(), (int)ft->encoding(), off)); }
1605 void sdc1(FloatRegister ft, Address dst);
1606 void swc1(FloatRegister ft, Register base, int off) { emit_long(insn_ORRI(swc1_op, (int)base->encoding(), (int)ft->encoding(), off)); }
1607 void swc1(FloatRegister ft, Address dst);
1610 void int3();
1611 static void print_instruction(int);
1612 int patched_branch(int dest_pos, int inst, int inst_pos);
1613 int branch_destination(int inst, int pos);
1615 // Loongson extension
1617 // gssq/gslq/gssqc1/gslqc1: vAddr = sign_extend(offset << 4 ) + GPR[base]. Therefore, the off should be ">> 4".
1618 void gslble(Register rt, Register base, Register bound) {
1619 emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gslble_op);
1620 }
1622 void gslbgt(Register rt, Register base, Register bound) {
1623 emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gslbgt_op);
1624 }
1626 void gslhle(Register rt, Register base, Register bound) {
1627 emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gslhle_op);
1628 }
1630 void gslhgt(Register rt, Register base, Register bound) {
1631 emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gslhgt_op);
1632 }
1634 void gslwle(Register rt, Register base, Register bound) {
1635 emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gslwle_op);
1636 }
1638 void gslwgt(Register rt, Register base, Register bound) {
1639 emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gslwgt_op);
1640 }
1642 void gsldle(Register rt, Register base, Register bound) {
1643 emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gsldle_op);
1644 }
1646 void gsldgt(Register rt, Register base, Register bound) {
1647 emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gsldgt_op);
1648 }
1650 void gslwlec1(FloatRegister rt, Register base, Register bound) {
1651 emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gslwlec1_op);
1652 }
1654 void gslwgtc1(FloatRegister rt, Register base, Register bound) {
1655 emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gslwgtc1_op);
1656 }
1658 void gsldlec1(FloatRegister rt, Register base, Register bound) {
1659 emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gsldlec1_op);
1660 }
1662 void gsldgtc1(FloatRegister rt, Register base, Register bound) {
1663 emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gsldgtc1_op);
1664 }
1666 void gslq(Register rq, Register rt, Register base, int off) {
1667 assert(!(off & 0xF), "gslq: the low 4 bits of off must be 0");
1668 off = off >> 4;
1669 assert(is_simm(off, 9),"gslq: off exceeds 9 bits");
1670 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() );
1671 }
1673 void gslqc1(FloatRegister rq, FloatRegister rt, Register base, int off) {
1674 assert(!(off & 0xF), "gslqc1: the low 4 bits of off must be 0");
1675 off = off >> 4;
1676 assert(is_simm(off, 9),"gslqc1: off exceeds 9 bits");
1677 emit_long((gs_lwc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | 1 << 15 | (low(off, 9) << 6) | gslq_op | (int)rq->encoding() );
1678 }
1680 void gssble(Register rt, Register base, Register bound) {
1681 emit_long((gs_swc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gssble_op);
1682 }
1684 void gssbgt(Register rt, Register base, Register bound) {
1685 emit_long((gs_swc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gssbgt_op);
1686 }
1688 void gsshle(Register rt, Register base, Register bound) {
1689 emit_long((gs_swc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gsshle_op);
1690 }
1692 void gsshgt(Register rt, Register base, Register bound) {
1693 emit_long((gs_swc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gsshgt_op);
1694 }
1696 void gsswle(Register rt, Register base, Register bound) {
1697 emit_long((gs_swc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gsswle_op);
1698 }
1700 void gsswgt(Register rt, Register base, Register bound) {
1701 emit_long((gs_swc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gsswgt_op);
1702 }
1704 void gssdle(Register rt, Register base, Register bound) {
1705 emit_long((gs_swc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gssdle_op);
1706 }
1708 void gssdgt(Register rt, Register base, Register bound) {
1709 emit_long((gs_swc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gssdgt_op);
1710 }
1712 void gsswlec1(FloatRegister rt, Register base, Register bound) {
1713 emit_long((gs_swc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gsswlec1_op);
1714 }
1716 void gsswgtc1(FloatRegister rt, Register base, Register bound) {
1717 emit_long((gs_swc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gsswgtc1_op);
1718 }
1720 void gssdlec1(FloatRegister rt, Register base, Register bound) {
1721 emit_long((gs_swc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gssdlec1_op);
1722 }
1724 void gssdgtc1(FloatRegister rt, Register base, Register bound) {
1725 emit_long((gs_swc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | ((int)bound->encoding() << 11) | 0 << 6 | gssdgtc1_op);
1726 }
1728 void gssq(Register rq, Register rt, Register base, int off) {
1729 assert(!(off & 0xF), "gssq: the low 4 bits of off must be 0");
1730 off = off >> 4;
1731 assert(is_simm(off, 9),"gssq: off exceeds 9 bits");
1732 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() );
1733 }
1735 void gssqc1(FloatRegister rq, FloatRegister rt, Register base, int off) {
1736 assert(!(off & 0xF), "gssqc1: the low 4 bits of off must be 0");
1737 off = off >> 4;
1738 assert(is_simm(off, 9),"gssqc1: off exceeds 9 bits");
1739 emit_long((gs_swc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | 1 << 15 | (low(off, 9) << 6) | gssq_op | (int)rq->encoding() );
1740 }
1742 //LDC2 & SDC2
1743 #define INSN(OPS, OP) \
1744 assert(is_simm(off, 8), "NAME: off exceeds 8 bits"); \
1745 assert(UseLEXT1, "check UseLEXT1"); \
1746 emit_long( (OPS << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) | \
1747 ((int)index->encoding() << 11) | (low(off, 8) << 3) | OP);
1749 #define INSN_LDC2(NAME, op) \
1750 void NAME(Register rt, Register base, Register index, int off) { \
1751 INSN(gs_ldc2_op, op) \
1752 }
1754 #define INSN_LDC2_F(NAME, op) \
1755 void NAME(FloatRegister rt, Register base, Register index, int off) { \
1756 INSN(gs_ldc2_op, op) \
1757 }
1759 #define INSN_SDC2(NAME, op) \
1760 void NAME(Register rt, Register base, Register index, int off) { \
1761 INSN(gs_sdc2_op, op) \
1762 }
1764 #define INSN_SDC2_F(NAME, op) \
1765 void NAME(FloatRegister rt, Register base, Register index, int off) { \
1766 INSN(gs_sdc2_op, op) \
1767 }
1769 /*
1770 void gslbx(Register rt, Register base, Register index, int off) {
1771 assert(is_simm(off, 8), "gslbx: off exceeds 8 bits");
1772 assert(UseLEXT1, "check UseLEXT1");
1773 emit_long( (gs_ldc2_op << 26) | ((int)base->encoding() << 21) | ((int)rt->encoding() << 16) |
1774 ((int)index->encoding() << 11) | (low(off, 8) << 3) | gslbx_op);
1775 void gslbx(Register rt, Register base, Register index, int off) {INSN(gs_ldc2_op, gslbx_op);}
1777 INSN_LDC2(gslbx, gslbx_op)
1778 INSN_LDC2(gslhx, gslhx_op)
1779 INSN_LDC2(gslwx, gslwx_op)
1780 INSN_LDC2(gsldx, gsldx_op)
1781 INSN_LDC2_F(gslwxc1, gslwxc1_op)
1782 INSN_LDC2_F(gsldxc1, gsldxc1_op)
1784 INSN_SDC2(gssbx, gssbx_op)
1785 INSN_SDC2(gsshx, gsshx_op)
1786 INSN_SDC2(gsswx, gsswx_op)
1787 INSN_SDC2(gssdx, gssdx_op)
1788 INSN_SDC2_F(gsswxc1, gsswxc1_op)
1789 INSN_SDC2_F(gssdxc1, gssdxc1_op)
1790 */
1791 void gslbx(Register rt, Register base, Register index, int off) {INSN(gs_ldc2_op, gslbx_op) }
1792 void gslhx(Register rt, Register base, Register index, int off) {INSN(gs_ldc2_op, gslhx_op) }
1793 void gslwx(Register rt, Register base, Register index, int off) {INSN(gs_ldc2_op, gslwx_op) }
1794 void gsldx(Register rt, Register base, Register index, int off) {INSN(gs_ldc2_op, gsldx_op) }
1795 void gslwxc1(FloatRegister rt, Register base, Register index, int off) {INSN(gs_ldc2_op, gslwxc1_op) }
1796 void gsldxc1(FloatRegister rt, Register base, Register index, int off) {INSN(gs_ldc2_op, gsldxc1_op) }
1798 void gssbx(Register rt, Register base, Register index, int off) {INSN(gs_sdc2_op, gssbx_op) }
1799 void gsshx(Register rt, Register base, Register index, int off) {INSN(gs_sdc2_op, gsshx_op) }
1800 void gsswx(Register rt, Register base, Register index, int off) {INSN(gs_sdc2_op, gsswx_op) }
1801 void gssdx(Register rt, Register base, Register index, int off) {INSN(gs_sdc2_op, gssdx_op) }
1802 void gsswxc1(FloatRegister rt, Register base, Register index, int off) {INSN(gs_sdc2_op, gsswxc1_op) }
1803 void gssdxc1(FloatRegister rt, Register base, Register index, int off) {INSN(gs_sdc2_op, gssdxc1_op) }
1805 #undef INSN
1806 #undef INSN_LDC2
1807 #undef INSN_LDC2_F
1808 #undef INSN_SDC2
1809 #undef INSN_SDC2_F
1811 // cpucfg on Loongson CPUs above 3A4000
1812 void cpucfg(Register rd, Register rs) { emit_long((gs_lwc2_op << 26) | ((int)rs->encoding() << 21) | (0b01000 << 16) | ((int)rd->encoding() << 11) | ( 0b00100 << 6) | 0b011000);}
1815 public:
1816 // Creation
1817 Assembler(CodeBuffer* code) : AbstractAssembler(code) {
1818 #ifdef CHECK_DELAY
1819 delay_state = no_delay;
1820 #endif
1821 }
1823 // Decoding
1824 static address locate_operand(address inst, WhichOperand which);
1825 static address locate_next_instruction(address inst);
1826 };
1830 #endif // CPU_MIPS_VM_ASSEMBLER_MIPS_HPP