2 /*---------------------------------------------------------------*/
3 /*--- begin host_nanomips_isel.c ---*/
4 /*---------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2017-2018 RT-RK
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation; either version 2 of the
15 License, or (at your option) any later version.
17 This program is distributed in the hope that it will be useful, but
18 WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
27 The GNU General Public License is contained in the file COPYING.
30 #include "libvex_basictypes.h"
31 #include "libvex_ir.h"
34 #include "main_util.h"
35 #include "main_globals.h"
36 #include "host_generic_regs.h"
37 #include "host_nanomips_defs.h"
39 /*---------------------------------------------------------*/
40 /*--- Register Usage Conventions ---*/
41 /*---------------------------------------------------------*/
52 static UInt hwcaps_host
= 0;
54 /* GPR register class for NANOMIPS */
55 #define HRcGPR HRcInt32
57 /*---------------------------------------------------------*/
59 /*---------------------------------------------------------*/
61 /* This carries around:
63 - A mapping from IRTemp to IRType, giving the type of any IRTemp we
64 might encounter. This is computed before insn selection starts,
67 - A mapping from IRTemp to HReg. This tells the insn selector
68 which virtual register(s) are associated with each IRTemp
69 temporary. This is computed before insn selection starts, and
70 does not change. We expect this mapping to map precisely the
71 same set of IRTemps as the type mapping does.
73 - vregmap holds the primary register for the IRTemp.
74 - vregmapHI is only used for 64-bit integer-typed
75 IRTemps. It holds the identity of a second
76 32-bit virtual HReg, which holds the high half
79 - The code array, that is, the insns selected so far.
81 - A counter, for generating new virtual registers.
83 - The host subarchitecture we are selecting insns for.
84 This is set at the start and does not change.
86 - A Bool for indicating whether we may generate chain-me
87 instructions for control flow transfers, or whether we must use
90 - The maximum guest address of any guest insn in this block.
91 Actually, the address of the highest-addressed byte from any insn
92 in this block. Is set at the start and does not change. This is
93 used for detecting jumps which are definitely forward-edges from
94 this block, and therefore can be made (chained) to the fast entry
95 point of the destination, thereby avoiding the destination's
98 Note, this is all (well, mostly) host-independent.
103 /* Constant -- are set at the start and do not change. */
112 Bool chainingAllowed
;
115 /* These are modified as we go along. */
120 static HReg
lookupIRTemp(ISelEnv
* env
, IRTemp tmp
)
122 vassert(tmp
< env
->n_vregmap
);
123 return env
->vregmap
[tmp
];
126 static void lookupIRTemp64(HReg
* vrHI
, HReg
* vrLO
, ISelEnv
* env
, IRTemp tmp
)
128 vassert(tmp
< env
->n_vregmap
);
129 vassert(!hregIsInvalid(env
->vregmapHI
[tmp
]));
130 *vrLO
= env
->vregmap
[tmp
];
131 *vrHI
= env
->vregmapHI
[tmp
];
134 static void addInstr(ISelEnv
* env
, NANOMIPSInstr
* instr
)
136 addHInstr(env
->code
, instr
);
138 if (vex_traceflags
& VEX_TRACE_VCODE
) {
139 ppNANOMIPSInstr(instr
);
144 static HReg
newVRegI(ISelEnv
* env
)
146 HReg reg
= mkHReg(True
/* virtual reg */,
147 HRcGPR
, 0 /* enc */, env
->vreg_ctr
);
152 /*---------------------------------------------------------*/
153 /*--- ISEL: Forward declarations ---*/
154 /*---------------------------------------------------------*/
156 /* These are organised as iselXXX and iselXXX_wrk pairs. The
157 iselXXX_wrk do the real work, but are not to be called directly.
158 For each XXX, iselXXX calls its iselXXX_wrk counterpart, then
159 checks that all returned registers are virtual. You should not
160 call the _wrk version directly.
163 /* Compute an I1/I8/I16/I32 into a GPR. */
164 static HReg
iselWordExpr_R_wrk(ISelEnv
* env
, IRExpr
* e
);
165 static HReg
iselWordExpr_R(ISelEnv
* env
, IRExpr
* e
);
167 /* Compute an I64 into a pair of GPRs. */
168 static void iselInt64Expr_wrk(HReg
* rHi
, HReg
* rLo
, ISelEnv
* env
, IRExpr
* e
);
169 static void iselInt64Expr(HReg
* rHi
, HReg
* rLo
, ISelEnv
* env
, IRExpr
* e
);
171 /*---------------------------------------------------------*/
172 /*--- ISEL: Misc helpers ---*/
173 /*---------------------------------------------------------*/
175 /* Make an int reg-reg move. */
176 static inline NANOMIPSInstr
*mk_iMOVds_RR(HReg r_dst
, HReg r_src
)
178 vassert(hregClass(r_dst
) == hregClass(r_src
));
179 vassert(hregClass(r_src
) == HRcInt32
);
180 return NANOMIPSInstr_Alu(NMalu_OR
, r_dst
, r_src
, r_src
);
183 /* Extract sign-extended value from IRConst */
184 static inline Int
extractConst(IRConst
*c
)
191 return (Int
)(Short
)c
->Ico
.U16
;
194 return (Int
)(Char
)c
->Ico
.U8
;
200 vpanic("NANOMIPSisel_extractConst() fails");
204 /*---------------------------------------------------------*/
205 /*--- ISEL: Function call helpers ---*/
206 /*---------------------------------------------------------*/
208 /* Used only in doHelperCall. See big comment in doHelperCall re
209 handling of register-parameter args. This function figures out
210 whether evaluation of an expression might require use of a fixed
211 register. If in doubt return True (safe but suboptimal).
213 static Bool
mightRequireFixedRegs(IRExpr
* e
)
226 /* Do a complete function call. |guard| is a Ity_Bit expression
227 indicating whether or not the call happens. If guard==NULL, the
228 call is unconditional. |retloc| is set to indicate where the
229 return value is after the call. The caller (of this fn) must
230 generate code to add |stackAdjustAfterCall| to the stack pointer
231 after the call is done. */
233 static void doHelperCall(/*OUT*/ RetLoc
* retloc
,
243 UInt n_args
, i
, argreg
, nGSPTRs
, argiregs
;
244 HReg cond
= INVALID_HREG
;
246 vassert((retty
== Ity_INVALID
) ||
247 (retty
== Ity_I32
) ||
248 (retty
== Ity_I64
) ||
251 /* NANOMIPS P32 calling convention: up to eight registers ($a0 ... $a7)
252 are allowed to be used for passing integer arguments. */
254 /* The return type can be I{32,16,8}.
255 |args| may contain IRExpr_GSPTR(), in which case the value
256 in the guest state pointer register is passed as the
257 corresponding argument. */
259 *retloc
= mk_RetLoc_INVALID();
263 for (i
= 0; args
[i
]; i
++) {
264 IRExpr
* arg
= args
[i
];
266 if (UNLIKELY(arg
->tag
== Iex_GSPTR
)) {
273 vassert(nGSPTRs
<= 1);
274 vassert(n_args
<= NANOMIPS_N_REGPARMS
);
276 argregs
[0] = hregNANOMIPS_GPR4();
277 argregs
[1] = hregNANOMIPS_GPR5();
278 argregs
[2] = hregNANOMIPS_GPR6();
279 argregs
[3] = hregNANOMIPS_GPR7();
280 argregs
[4] = hregNANOMIPS_GPR8();
281 argregs
[5] = hregNANOMIPS_GPR9();
282 argregs
[6] = hregNANOMIPS_GPR10();
283 argregs
[7] = hregNANOMIPS_GPR11();
285 tmpregs
[0] = tmpregs
[1] = tmpregs
[2] =
286 tmpregs
[3] = tmpregs
[4] = tmpregs
[5] =
287 tmpregs
[6] = tmpregs
[7] = INVALID_HREG
;
289 /* First decide which scheme (slow or fast) is to be used. First assume the
290 fast scheme, and select slow if any contraindications (wow) appear. */
294 vassert(typeOfIRExpr(env
->type_env
, guard
) == Ity_I1
);
296 if (guard
->tag
!= Iex_Const
|| !guard
->Iex
.Const
.con
->Ico
.U1
) {
298 cond
= iselWordExpr_R(env
, guard
);
303 for (i
= 0; i
< n_args
; i
++) {
304 if (mightRequireFixedRegs(args
[i
])) {
311 /* At this point the scheme to use has been established. Generate
312 code to get the arg values into the argument rregs. */
316 for (i
= 0; i
< n_args
; i
++) {
317 IRExpr
* arg
= args
[i
];
318 IRType aTy
= Ity_INVALID
;
319 vassert(argreg
< NANOMIPS_N_REGPARMS
);
321 if (LIKELY(!is_IRExpr_VECRET_or_GSPTR(arg
)))
322 aTy
= typeOfIRExpr(env
->type_env
, arg
);
329 argiregs
|= (1 << (argreg
+ 4));
330 addInstr(env
, mk_iMOVds_RR(argregs
[argreg
],
331 iselWordExpr_R(env
, arg
)));
338 argiregs
|= (1 << (argreg
+ 4));
341 vassert(argreg
+ 1 < NANOMIPS_N_REGPARMS
);
344 iselInt64Expr(&rHi
, &rLo
, env
, arg
);
345 argiregs
|= (1 << (argreg
+ 4));
346 addInstr(env
, mk_iMOVds_RR(argregs
[argreg
++], rHi
));
347 argiregs
|= (1 << (argreg
+ 4));
348 addInstr(env
, mk_iMOVds_RR(argregs
[argreg
], rLo
));
354 vassert(arg
->tag
== Iex_GSPTR
);
355 addInstr(env
, mk_iMOVds_RR(argregs
[argreg
], GuestStatePointer
));
363 for (i
= 0; i
< n_args
; i
++) {
364 IRExpr
* arg
= args
[i
];
365 IRType aTy
= Ity_INVALID
;
366 vassert(argreg
< NANOMIPS_N_REGPARMS
);
368 if (LIKELY(!is_IRExpr_VECRET_or_GSPTR(arg
)))
369 aTy
= typeOfIRExpr(env
->type_env
, arg
);
376 tmpregs
[argreg
] = iselWordExpr_R(env
, arg
);
387 vassert(argreg
+ 1 < NANOMIPS_N_REGPARMS
);
389 iselInt64Expr(&raHi
, &raLo
, env
, arg
);
390 tmpregs
[argreg
] = raLo
;
392 tmpregs
[argreg
] = raHi
;
399 vassert(arg
->tag
== Iex_GSPTR
);
400 tmpregs
[argreg
] = GuestStatePointer
;
405 for (i
= 0; i
< argreg
; i
++) {
406 if (hregIsInvalid(tmpregs
[i
]))
409 /* None of these insns, including any spill code that might
410 be generated, may alter the condition codes. */
411 argiregs
|= (1 << (i
+ 4));
412 addInstr(env
, mk_iMOVds_RR(argregs
[i
], tmpregs
[i
]));
419 *retloc
= mk_RetLoc_simple(RLPri_None
);
423 *retloc
= mk_RetLoc_simple(RLPri_2Int
);
429 *retloc
= mk_RetLoc_simple(RLPri_Int
);
436 addInstr(env
, NANOMIPSInstr_Call((Addr
)cee
->addr
, argiregs
, cond
, *retloc
));
439 /*---------------------------------------------------------*/
440 /*--- ISEL: Integer expressions (64/32/16/8 bit) ---*/
441 /*---------------------------------------------------------*/
443 /* Select insns for an integer-typed expression, and add them to the
444 code list. Return a reg holding the result. This reg will be a
445 virtual register. THE RETURNED REG MUST NOT BE MODIFIED. If you
446 want to modify it, ask for a new vreg, copy it in there, and modify
447 the copy. The register allocator will do its best to map both
448 vregs to the same real register, so the copies will often disappear
451 This should handle expressions of 64, 32, 16 and 8-bit type.
452 All results are returned in a (mode64 ? 64bit : 32bit) register.
453 For 16- and 8-bit expressions, the upper (32/48/56 : 16/24) bits
454 are arbitrary, so you should mask or sign extend partial values
457 static HReg
iselWordExpr_R(ISelEnv
* env
, IRExpr
* e
)
459 HReg r
= iselWordExpr_R_wrk(env
, e
);
460 /* sanity checks ... */
461 vassert(hregClass(r
) == HRcGPR
);
462 vassert(hregIsVirtual(r
));
466 static HReg
iselWordExpr_R_wrk(ISelEnv
* env
, IRExpr
* e
)
468 IRType ty
= typeOfIRExpr(env
->type_env
, e
);
469 vassert(ty
== Ity_I1
|| ty
== Ity_I8
|| ty
== Ity_I16
|| ty
== Ity_I32
);
473 return lookupIRTemp(env
, e
->Iex
.RdTmp
.tmp
);
476 HReg r_dst
= newVRegI(env
);
477 HReg r_addr
= iselWordExpr_R(env
, e
->Iex
.Load
.addr
);
478 addInstr(env
, NANOMIPSInstr_Load(sizeofIRType(ty
), r_dst
, r_addr
, 0));
483 vassert(ty
== Ity_I8
|| ty
== Ity_I16
|| ty
== Ity_I32
);
484 HReg r_dst
= newVRegI(env
);
485 vassert((e
->Iex
.Get
.offset
< 0x1000) && (e
->Iex
.Get
.offset
>= 0));
486 addInstr(env
, NANOMIPSInstr_Load(sizeofIRType(ty
), r_dst
,
494 NANOMIPSCondCode ccOp
;
496 switch (e
->Iex
.Binop
.op
) {
559 aluOp
= NMalu_INVALID
;
563 if (aluOp
!= NMalu_INVALID
) {
564 HReg r_dst
= newVRegI(env
);
565 HReg r_srcL
= iselWordExpr_R(env
, e
->Iex
.Binop
.arg1
);
567 /* Optimization: If seccond argument is Const and
568 ALU operation can be converted to IMM operation */
569 if ((aluOp
<= NMalu_AND
) &&
570 (e
->Iex
.Binop
.arg2
->tag
== Iex_Const
)) {
572 UInt val
= extractConst(e
->Iex
.Binop
.arg2
->Iex
.Const
.con
);
575 ((val
< 0x1000) && (aluOp
>= NMalu_OR
))) {
576 NANOMIPSImmOp immOp
= (NANOMIPSImmOp
)aluOp
;
577 addInstr(env
, NANOMIPSInstr_Imm(immOp
, r_dst
, r_srcL
,
583 HReg r_srcR
= iselWordExpr_R(env
, e
->Iex
.Binop
.arg2
);
584 addInstr(env
, NANOMIPSInstr_Alu(aluOp
, r_dst
, r_srcL
, r_srcR
));
588 switch (e
->Iex
.Binop
.op
) {
619 if (ccOp
!= NMcc_INVALID
) {
620 HReg dst
= newVRegI(env
);
621 HReg r1
= iselWordExpr_R(env
, e
->Iex
.Binop
.arg1
);
622 HReg r2
= iselWordExpr_R(env
, e
->Iex
.Binop
.arg2
);
623 addInstr(env
, NANOMIPSInstr_Cmp(ccOp
, dst
, r1
, r2
));
627 switch (e
->Iex
.Binop
.op
) {
629 HReg r_dst
= newVRegI(env
);
630 HReg r_tmp
= newVRegI(env
);
631 HReg r_srcL
= iselWordExpr_R(env
, e
->Iex
.Binop
.arg1
);
632 HReg r_srcR
= iselWordExpr_R(env
, e
->Iex
.Binop
.arg2
);
633 addInstr(env
, NANOMIPSInstr_Imm(NMimm_ANDI
, r_dst
, r_srcL
, 0xFF));
634 addInstr(env
, NANOMIPSInstr_Imm(NMimm_ANDI
, r_tmp
, r_srcR
, 0xFF));
635 addInstr(env
, NANOMIPSInstr_Alu(NMalu_MULU
, r_dst
, r_dst
, r_tmp
));
640 HReg r_dst
= newVRegI(env
);
641 HReg r_tmp
= newVRegI(env
);
642 HReg r_mask
= newVRegI(env
);
643 HReg r_srcL
= iselWordExpr_R(env
, e
->Iex
.Binop
.arg1
);
644 HReg r_srcR
= iselWordExpr_R(env
, e
->Iex
.Binop
.arg2
);
645 addInstr(env
, NANOMIPSInstr_Imm(NMimm_LI
, r_mask
, INVALID_HREG
,
647 addInstr(env
, NANOMIPSInstr_Alu(NMalu_AND
, r_dst
, r_srcL
, r_mask
));
648 addInstr(env
, NANOMIPSInstr_Alu(NMalu_AND
, r_tmp
, r_srcR
, r_mask
));
649 addInstr(env
, NANOMIPSInstr_Alu(NMalu_MULU
, r_dst
, r_dst
, r_tmp
));
655 HReg r_dst
= newVRegI(env
);
656 HReg r_tmp
= newVRegI(env
);
657 HReg r_srcL
= iselWordExpr_R(env
, e
->Iex
.Binop
.arg1
);
658 HReg r_srcR
= iselWordExpr_R(env
, e
->Iex
.Binop
.arg2
);
660 switch (e
->Iex
.Binop
.op
) {
662 addInstr(env
, NANOMIPSInstr_Imm(NMimm_SLL
, r_tmp
, r_srcL
, 8));
663 addInstr(env
, NANOMIPSInstr_Imm(NMimm_ANDI
, r_dst
, r_srcR
,
668 HReg r_mask
= newVRegI(env
);
669 addInstr(env
, NANOMIPSInstr_Imm(NMimm_LI
, r_mask
,
670 INVALID_HREG
, 0xFFFF));
671 addInstr(env
, NANOMIPSInstr_Imm(NMimm_SLL
, r_tmp
,
673 addInstr(env
, NANOMIPSInstr_Alu(NMalu_AND
, r_dst
, r_srcR
,
682 addInstr(env
, NANOMIPSInstr_Alu(NMalu_OR
, r_dst
, r_dst
, r_tmp
));
690 vex_printf("Unimplemented binop ");
691 ppIROp(e
->Iex
.Binop
.op
);
698 IROp op_unop
= e
->Iex
.Unop
.op
;
704 HReg r_dst
= newVRegI(env
);
705 HReg r_src
= iselWordExpr_R(env
, e
->Iex
.Unop
.arg
);
706 addInstr(env
, NANOMIPSInstr_Imm(NMimm_SGN
, r_dst
, r_src
, 1));
712 HReg r_dst
= newVRegI(env
);
713 HReg r_src
= iselWordExpr_R(env
, e
->Iex
.Unop
.arg
);
714 addInstr(env
, NANOMIPSInstr_Imm(NMimm_SGN
, r_dst
, r_src
, 8));
719 HReg r_dst
= newVRegI(env
);
720 HReg r_src
= iselWordExpr_R(env
, e
->Iex
.Unop
.arg
);
721 addInstr(env
, NANOMIPSInstr_Imm(NMimm_SGN
, r_dst
, r_src
, 16));
730 return iselWordExpr_R(env
, e
->Iex
.Unop
.arg
);
734 iselInt64Expr(&rHi
, &rLo
, env
, e
->Iex
.Unop
.arg
);
740 iselInt64Expr(&rHi
, &rLo
, env
, e
->Iex
.Unop
.arg
);
745 HReg r_dst
= newVRegI(env
);
746 HReg r_src
= iselWordExpr_R(env
, e
->Iex
.Unop
.arg
);
747 addInstr(env
, NANOMIPSInstr_Imm(NMimm_ANDI
, r_dst
, r_src
, 1));
753 HReg r_dst
= newVRegI(env
);
754 HReg r_src
= iselWordExpr_R(env
, e
->Iex
.Unop
.arg
);
755 addInstr(env
, NANOMIPSInstr_Imm(NMimm_ANDI
, r_dst
, r_src
,
761 HReg r_dst
= newVRegI(env
);
762 HReg r_src
= iselWordExpr_R(env
, e
->Iex
.Unop
.arg
);
763 addInstr(env
, NANOMIPSInstr_Imm(NMimm_LI
, r_dst
, INVALID_HREG
,
765 addInstr(env
, NANOMIPSInstr_Alu(NMalu_AND
, r_dst
, r_dst
, r_src
));
770 HReg r_dst
= newVRegI(env
);
771 HReg r_src
= iselWordExpr_R(env
, e
->Iex
.Unop
.arg
);
772 addInstr(env
, NANOMIPSInstr_Imm(NMimm_XORI
, r_dst
, r_src
, 1));
779 HReg r_dst
= newVRegI(env
);
780 HReg r_src
= iselWordExpr_R(env
, e
->Iex
.Unop
.arg
);
781 addInstr(env
, NANOMIPSInstr_Alu(NMalu_NOR
, r_dst
, r_src
, r_src
));
786 HReg r_dst
= newVRegI(env
);
787 HReg r_src
= iselWordExpr_R(env
, e
->Iex
.Unop
.arg
);
788 addInstr(env
, NANOMIPSInstr_Imm(NMimm_SRA
, r_dst
, r_src
, 16));
793 HReg r_dst
= newVRegI(env
);
794 HReg r_src
= iselWordExpr_R(env
, e
->Iex
.Unop
.arg
);
795 addInstr(env
, NANOMIPSInstr_Imm(NMimm_SRA
, r_dst
, r_src
, 8));
802 HReg r_dst
= newVRegI(env
);
803 HReg r_src
= iselWordExpr_R(env
, e
->Iex
.Unop
.arg
);
804 addInstr(env
, NANOMIPSInstr_Cmp(NMcc_NE
, r_dst
, r_src
,
809 case Iop_CmpwNEZ32
: {
810 HReg r_dst
= newVRegI(env
);
811 HReg r_src
= iselWordExpr_R(env
, e
->Iex
.Unop
.arg
);
812 addInstr(env
, NANOMIPSInstr_Cmp(NMcc_NE
, r_dst
, r_src
,
814 addInstr(env
, NANOMIPSInstr_Imm(NMimm_SGN
, r_dst
, r_dst
, 1));
819 HReg r_dst
= newVRegI(env
);
820 HReg r_src
= iselWordExpr_R(env
, e
->Iex
.Unop
.arg
);
821 addInstr(env
, NANOMIPSInstr_Unary(NMun_CLZ
, r_dst
, r_src
));
828 HReg r_dst
= newVRegI(env
);
829 HReg r_src
= iselWordExpr_R(env
, e
->Iex
.Unop
.arg
);
830 addInstr(env
, NANOMIPSInstr_Alu(NMalu_SUB
, r_dst
, Zero
, r_src
));
831 addInstr(env
, NANOMIPSInstr_Alu(NMalu_OR
, r_dst
, r_dst
,
840 vex_printf("Unimplemented unop ");
841 ppIROp(e
->Iex
.Unop
.op
);
846 HReg dst
= newVRegI(env
);
847 HReg src1
= iselWordExpr_R(env
, e
->Iex
.Qop
.details
->arg1
);
848 UChar src2
= e
->Iex
.Qop
.details
->arg2
->Iex
.Const
.con
->Ico
.U8
;
849 UChar src3
= e
->Iex
.Qop
.details
->arg3
->Iex
.Const
.con
->Ico
.U8
;
850 UChar src4
= e
->Iex
.Qop
.details
->arg4
->Iex
.Const
.con
->Ico
.U8
;
851 UInt imm
= (src3
<< 6) | (src4
<< 6) | src2
;
852 switch (e
->Iex
.Qop
.details
->op
) {
854 addInstr(env
, NANOMIPSInstr_Imm(NMimm_ROTX
, dst
, src1
, imm
));
863 vassert(typeOfIRExpr(env
->type_env
, e
->Iex
.ITE
.cond
) == Ity_I1
);
864 HReg r0
= iselWordExpr_R(env
, e
->Iex
.ITE
.iffalse
);
865 HReg r1
= iselWordExpr_R(env
, e
->Iex
.ITE
.iftrue
);
866 HReg r_cond
= iselWordExpr_R(env
, e
->Iex
.ITE
.cond
);
867 HReg r_dst
= newVRegI(env
);
868 addInstr(env
, mk_iMOVds_RR(r_dst
, r0
));
869 addInstr(env
, NANOMIPSInstr_MoveCond(NMMoveCond_movn
, r_dst
,
875 HReg r_dst
= newVRegI(env
);
876 addInstr(env
, NANOMIPSInstr_Imm(NMimm_LI
, r_dst
, INVALID_HREG
,
877 extractConst(e
->Iex
.Const
.con
)));
882 HReg r_dst
= newVRegI(env
);
884 RetLoc rloc
= mk_RetLoc_INVALID();
886 /* Be very restrictive for now. Only 32-bit ints allowed for
887 args, and 32 bits for return type. Don't forget to change
888 the RetLoc if more return types are allowed in future. */
889 vassert(Ity_I32
== e
->Iex
.CCall
.retty
);
891 /* Marshal args, do the call, clear stack. */
892 doHelperCall(&rloc
, env
, NULL
/*guard*/, e
->Iex
.CCall
.cee
,
893 e
->Iex
.CCall
.retty
, e
->Iex
.CCall
.args
);
894 vassert(is_sane_RetLoc(rloc
));
895 vassert(rloc
.pri
== RLPri_Int
);
896 vassert(addToSp
== 0);
897 addInstr(env
, mk_iMOVds_RR(r_dst
, hregNANOMIPS_GPR4()));
906 vpanic("iselWordExpr_R(NANOMIPS): cannot reduce tree");
909 /*---------------------------------------------------------*/
910 /*--- ISEL: Integer expressions (64 bit) ---*/
911 /*---------------------------------------------------------*/
913 /* Compute a 64-bit value into the register pair HI, LO.
914 HI and LO must not be changed by subsequent code emitted
916 static void iselInt64Expr(HReg
* rHi
, HReg
* rLo
, ISelEnv
* env
, IRExpr
* e
)
918 iselInt64Expr_wrk(rHi
, rLo
, env
, e
);
919 vassert(hregClass(*rHi
) == HRcInt32
);
920 vassert(hregIsVirtual(*rHi
));
921 vassert(hregClass(*rLo
) == HRcInt32
);
922 vassert(hregIsVirtual(*rLo
));
925 static void iselInt64Expr_wrk(HReg
* rHi
, HReg
* rLo
, ISelEnv
* env
,
929 vassert(typeOfIRExpr(env
->type_env
, e
) == Ity_I64
);
933 lookupIRTemp64(rHi
, rLo
, env
, e
->Iex
.RdTmp
.tmp
);
937 HReg tLo
= newVRegI(env
);
938 HReg tHi
= newVRegI(env
);
939 HReg r_addr
= iselWordExpr_R(env
, e
->Iex
.Load
.addr
);
940 addInstr(env
, NANOMIPSInstr_Load(4, tLo
, r_addr
, 0));
941 addInstr(env
, NANOMIPSInstr_Load(4, tHi
, r_addr
, 4));
948 HReg tLo
= newVRegI(env
);
949 HReg tHi
= newVRegI(env
);
950 vassert((e
->Iex
.Get
.offset
< 0x1000 - 4) && (e
->Iex
.Get
.offset
>= 0));
951 addInstr(env
, NANOMIPSInstr_Load(4, tLo
, GuestStatePointer
,
953 addInstr(env
, NANOMIPSInstr_Load(4, tHi
, GuestStatePointer
,
954 e
->Iex
.Get
.offset
+ 4));
961 switch (e
->Iex
.Binop
.op
) {
962 case Iop_DivModS32to32
: {
963 HReg r_srcL
= iselWordExpr_R(env
, e
->Iex
.Binop
.arg1
);
964 HReg r_srcR
= iselWordExpr_R(env
, e
->Iex
.Binop
.arg2
);
965 HReg tLo
= newVRegI(env
);
966 HReg tHi
= newVRegI(env
);
967 addInstr(env
, NANOMIPSInstr_Alu(NMalu_DIV
, tLo
, r_srcL
, r_srcR
));
968 addInstr(env
, NANOMIPSInstr_Alu(NMalu_MOD
, tHi
, r_srcL
, r_srcR
));
974 case Iop_DivModU32to32
: {
975 HReg r_srcL
= iselWordExpr_R(env
, e
->Iex
.Binop
.arg1
);
976 HReg r_srcR
= iselWordExpr_R(env
, e
->Iex
.Binop
.arg2
);
977 HReg tLo
= newVRegI(env
);
978 HReg tHi
= newVRegI(env
);
979 addInstr(env
, NANOMIPSInstr_Alu(NMalu_DIVU
, tLo
, r_srcL
, r_srcR
));
980 addInstr(env
, NANOMIPSInstr_Alu(NMalu_MODU
, tHi
, r_srcL
, r_srcR
));
987 HReg r_srcL
= iselWordExpr_R(env
, e
->Iex
.Binop
.arg1
);
988 HReg r_srcR
= iselWordExpr_R(env
, e
->Iex
.Binop
.arg2
);
989 HReg tLo
= newVRegI(env
);
990 HReg tHi
= newVRegI(env
);
991 addInstr(env
, NANOMIPSInstr_Alu(NMalu_MUL
, tLo
, r_srcL
, r_srcR
));
992 addInstr(env
, NANOMIPSInstr_Alu(NMalu_MUH
, tHi
, r_srcL
, r_srcR
));
999 HReg r_srcL
= iselWordExpr_R(env
, e
->Iex
.Binop
.arg1
);
1000 HReg r_srcR
= iselWordExpr_R(env
, e
->Iex
.Binop
.arg2
);
1001 HReg tLo
= newVRegI(env
);
1002 HReg tHi
= newVRegI(env
);
1003 addInstr(env
, NANOMIPSInstr_Alu(NMalu_MULU
, tLo
, r_srcL
, r_srcR
));
1004 addInstr(env
, NANOMIPSInstr_Alu(NMalu_MUHU
, tHi
, r_srcL
, r_srcR
));
1011 #if defined (_MIPSEL)
1013 HReg a0tmp
= newVRegI(env
);
1014 HReg a1tmp
= newVRegI(env
);
1015 HReg a2
= newVRegI(env
);
1016 HReg a3
= newVRegI(env
);
1017 HReg a4
= newVRegI(env
);
1019 iselInt64Expr(&a1
, &a0
, env
, e
->Iex
.Binop
.arg1
);
1020 sa
= iselWordExpr_R(env
, e
->Iex
.Binop
.arg2
);
1022 /* andi a2, %sa, 0x3f */
1023 addInstr(env
, NANOMIPSInstr_Imm(NMimm_ANDI
, a2
, sa
, 0x3f));
1024 /* nor a4, zero, a2 */
1025 addInstr(env
, NANOMIPSInstr_Alu(NMalu_NOR
, a4
, Zero
, a2
));
1027 addInstr(env
, NANOMIPSInstr_Imm(NMimm_SLL
, a3
, a1
, 0x1));
1028 /* sllv a3, a3, a4 */
1029 addInstr(env
, NANOMIPSInstr_Alu(NMalu_SLL
, a3
, a3
, a4
));
1030 /* srlv a0, a0, a2 */
1031 addInstr(env
, NANOMIPSInstr_Alu(NMalu_SRL
, a0tmp
, a0
, a2
));
1032 /* andi a4, a2, 0x20 */
1033 addInstr(env
, NANOMIPSInstr_Imm(NMimm_ANDI
, a4
, a2
, 0x20));
1034 /* srlv a2, a1, a2 */
1035 addInstr(env
, NANOMIPSInstr_Alu(NMalu_SRL
, a2
, a1
, a2
));
1037 addInstr(env
, NANOMIPSInstr_Alu(NMalu_OR
, a0tmp
, a0tmp
, a3
));
1039 addInstr(env
, mk_iMOVds_RR(a1tmp
, a2
));
1040 /* movn a1, zero, a4 */
1041 addInstr(env
, NANOMIPSInstr_MoveCond(NMMoveCond_movn
, a1tmp
,
1043 /* movn a0, a2, a4 */
1044 addInstr(env
, NANOMIPSInstr_MoveCond(NMMoveCond_movn
, a0tmp
,
1050 #elif defined (_MIPSEB)
1051 /* 64-bit logical shift right based on what gcc generates:
1065 /* unimplemented yet */
1072 *rHi
= iselWordExpr_R(env
, e
->Iex
.Binop
.arg1
);
1073 *rLo
= iselWordExpr_R(env
, e
->Iex
.Binop
.arg2
);
1078 HReg rHi_srcL
, rLo_srcL
;
1079 HReg rHi_srcR
, rLo_srcR
;
1080 HReg rHi_dst
= newVRegI(env
);
1081 HReg rLo_dst
= newVRegI(env
);
1082 iselInt64Expr(&rHi_srcL
, &rLo_srcL
, env
, e
->Iex
.Binop
.arg1
);
1083 iselInt64Expr(&rHi_srcR
, &rLo_srcR
, env
, e
->Iex
.Binop
.arg2
);
1084 addInstr(env
, NANOMIPSInstr_Alu(NMalu_OR
, rHi_dst
, rHi_srcL
,
1086 addInstr(env
, NANOMIPSInstr_Alu(NMalu_OR
, rLo_dst
, rLo_srcL
,
1098 vex_printf("Unimplemented binop ");
1099 ppIROp(e
->Iex
.Binop
.op
);
1106 switch (e
->Iex
.Unop
.op
) {
1108 HReg rHi_dst
= newVRegI(env
);
1109 HReg rLo_dst
= newVRegI(env
);
1110 HReg r_src
= iselWordExpr_R(env
, e
->Iex
.Unop
.arg
);
1111 addInstr(env
, NANOMIPSInstr_Imm(NMimm_SGN
, rLo_dst
, r_src
, 1));
1112 addInstr(env
, mk_iMOVds_RR(rHi_dst
, rLo_dst
));
1122 vex_printf("Unimplemented unop ");
1123 ppIROp(e
->Iex
.Unop
.op
);
1134 vpanic("iselInt64Expr(NANOMIPS): cannot reduce tree");
1137 /*---------------------------------------------------------*/
1138 /*--- ISEL: Statements ---*/
1139 /*---------------------------------------------------------*/
1140 static void iselStmt(ISelEnv
* env
, IRStmt
* stmt
)
1142 if (vex_traceflags
& VEX_TRACE_VCODE
) {
1143 vex_printf("\n-- ");
1148 switch (stmt
->tag
) {
1150 IRType tyd
= typeOfIRExpr(env
->type_env
, stmt
->Ist
.Store
.data
);
1151 HReg r_addr
= iselWordExpr_R(env
, stmt
->Ist
.Store
.addr
);
1153 if (tyd
== Ity_I8
|| tyd
== Ity_I16
|| tyd
== Ity_I32
) {
1154 HReg r_src
= iselWordExpr_R(env
, stmt
->Ist
.Store
.data
);
1155 addInstr(env
, NANOMIPSInstr_Store(sizeofIRType(tyd
),
1158 } else if (tyd
== Ity_I64
) {
1160 iselInt64Expr(&vHi
, &vLo
, env
, stmt
->Ist
.Store
.data
);
1161 addInstr(env
, NANOMIPSInstr_Store(4, r_addr
, 0, vLo
));
1162 addInstr(env
, NANOMIPSInstr_Store(4, r_addr
, 4, vHi
));
1170 IRType ty
= typeOfIRExpr(env
->type_env
, stmt
->Ist
.Put
.data
);
1171 vassert(stmt
->Ist
.Put
.offset
>= 0);
1173 if (ty
== Ity_I8
|| ty
== Ity_I16
|| ty
== Ity_I32
) {
1174 HReg r_src
= iselWordExpr_R(env
, stmt
->Ist
.Put
.data
);
1175 vassert(stmt
->Ist
.Put
.offset
< 0x1000);
1176 addInstr(env
, NANOMIPSInstr_Store(sizeofIRType(ty
),
1178 stmt
->Ist
.Put
.offset
, r_src
));
1180 } else if (ty
== Ity_I64
) {
1182 vassert(stmt
->Ist
.Put
.offset
< 0x1000 - 4);
1183 iselInt64Expr(&vHi
, &vLo
, env
, stmt
->Ist
.Put
.data
);
1184 addInstr(env
, NANOMIPSInstr_Store(4, GuestStatePointer
,
1185 stmt
->Ist
.Put
.offset
, vLo
));
1186 addInstr(env
, NANOMIPSInstr_Store(4, GuestStatePointer
,
1187 stmt
->Ist
.Put
.offset
+ 4,
1196 IRTemp tmp
= stmt
->Ist
.WrTmp
.tmp
;
1197 IRType ty
= typeOfIRTemp(env
->type_env
, tmp
);
1199 if (ty
== Ity_I1
|| ty
== Ity_I8
|| ty
== Ity_I16
||
1201 HReg r_dst
= lookupIRTemp(env
, tmp
);
1202 HReg r_src
= iselWordExpr_R(env
, stmt
->Ist
.WrTmp
.data
);
1203 addInstr(env
, mk_iMOVds_RR(r_dst
, r_src
));
1205 } else if (ty
== Ity_I64
) {
1206 HReg rHi
, rLo
, dstHi
, dstLo
;
1207 iselInt64Expr(&rHi
, &rLo
, env
, stmt
->Ist
.WrTmp
.data
);
1208 lookupIRTemp64(&dstHi
, &dstLo
, env
, tmp
);
1209 addInstr(env
, mk_iMOVds_RR(dstHi
, rHi
));
1210 addInstr(env
, mk_iMOVds_RR(dstLo
, rLo
));
1218 IRDirty
*d
= stmt
->Ist
.Dirty
.details
;
1219 IRType retty
= Ity_INVALID
;
1221 if (d
->tmp
!= IRTemp_INVALID
)
1222 retty
= typeOfIRTemp(env
->type_env
, d
->tmp
);
1224 vassert((retty
== Ity_INVALID
) ||
1225 (retty
== Ity_I32
) ||
1226 (retty
== Ity_I64
) ||
1227 (retty
== Ity_I8
) ||
1228 (retty
== Ity_I16
));
1230 /* Marshal args, do the call, clear stack, set the return value
1231 to 0x555..555 if this is a conditional call that returns a
1232 value and the call is skipped. */
1233 RetLoc rloc
= mk_RetLoc_INVALID();
1234 doHelperCall(&rloc
, env
, d
->guard
, d
->cee
, retty
, d
->args
);
1235 vassert(is_sane_RetLoc(rloc
));
1237 /* Now figure out what to do with the returned value, if any. */
1240 vassert(d
->tmp
== IRTemp_INVALID
);
1241 vassert(rloc
.pri
== RLPri_None
);
1248 HReg r_dst
= lookupIRTemp(env
, d
->tmp
);
1249 vassert(rloc
.pri
== RLPri_Int
);
1250 addInstr(env
, mk_iMOVds_RR(r_dst
, hregNANOMIPS_GPR4()));
1255 HReg rHi
= newVRegI(env
);
1256 HReg rLo
= newVRegI(env
);
1258 vassert(rloc
.pri
== RLPri_2Int
);
1259 addInstr(env
, mk_iMOVds_RR(rLo
, hregNANOMIPS_GPR4()));
1260 addInstr(env
, mk_iMOVds_RR(rHi
, hregNANOMIPS_GPR5()));
1261 lookupIRTemp64(&dstHi
, &dstLo
, env
, d
->tmp
);
1262 addInstr(env
, mk_iMOVds_RR(dstHi
, rHi
));
1263 addInstr(env
, mk_iMOVds_RR(dstLo
, rLo
));
1275 IRTemp res
= stmt
->Ist
.LLSC
.result
;
1276 IRType tyAddr
= typeOfIRExpr(env
->type_env
, stmt
->Ist
.LLSC
.addr
);
1278 if (tyAddr
!= Ity_I32
)
1281 if (stmt
->Ist
.LLSC
.storedata
== NULL
) {
1283 HReg r_addr
= iselWordExpr_R(env
, stmt
->Ist
.LLSC
.addr
);
1284 HReg r_dst
= lookupIRTemp(env
, res
);
1286 addInstr(env
, NANOMIPSInstr_LoadL(4, r_dst
, r_addr
, 0));
1290 HReg r_addr
= iselWordExpr_R(env
, stmt
->Ist
.LLSC
.addr
);
1291 HReg r_src
= iselWordExpr_R(env
, stmt
->Ist
.LLSC
.storedata
);
1292 HReg r_dst
= lookupIRTemp(env
, res
);
1294 addInstr(env
, mk_iMOVds_RR(r_dst
, r_src
));
1295 addInstr(env
, NANOMIPSInstr_StoreC(4, r_addr
, 0, r_dst
));
1301 if (stmt
->Ist
.CAS
.details
->oldHi
== IRTemp_INVALID
) {
1302 IRCAS
*cas
= stmt
->Ist
.CAS
.details
;
1303 HReg old
= lookupIRTemp(env
, cas
->oldLo
);
1304 HReg addr
= iselWordExpr_R(env
, cas
->addr
);
1305 HReg expd
= iselWordExpr_R(env
, cas
->expdLo
);
1306 HReg data
= iselWordExpr_R(env
, cas
->dataLo
);
1307 vassert(typeOfIRTemp(env
->type_env
, cas
->oldLo
) == Ity_I32
);
1308 addInstr(env
, NANOMIPSInstr_Cas(4, old
, old
, addr
, expd
, expd
, data
, data
));
1311 IRCAS
*cas
= stmt
->Ist
.CAS
.details
;
1312 HReg oldHi
= lookupIRTemp(env
, cas
->oldHi
);
1313 HReg oldLo
= lookupIRTemp(env
, cas
->oldLo
);
1314 HReg addr
= iselWordExpr_R(env
, cas
->addr
);
1315 HReg expdHi
= iselWordExpr_R(env
, cas
->expdHi
);
1316 HReg expdLo
= iselWordExpr_R(env
, cas
->expdLo
);
1317 HReg dataHi
= iselWordExpr_R(env
, cas
->dataHi
);
1318 HReg dataLo
= iselWordExpr_R(env
, cas
->dataLo
);
1319 vassert(typeOfIRTemp(env
->type_env
, cas
->oldLo
) == Ity_I32
);
1320 addInstr(env
, NANOMIPSInstr_Cas(8, oldLo
, oldHi
, addr
,
1321 expdLo
, expdHi
, dataLo
, dataHi
));
1331 Addr dst
= extractConst(stmt
->Ist
.Exit
.dst
);
1332 HReg cond
= iselWordExpr_R(env
, stmt
->Ist
.Exit
.guard
);
1334 switch (stmt
->Ist
.Exit
.jk
) {
1338 vassert(stmt
->Ist
.Exit
.offsIP
>= 0);
1339 vassert(stmt
->Ist
.Exit
.offsIP
<= 0x1000);
1341 if (env
->chainingAllowed
) {
1342 Bool toFastEP
= (dst
> (Addr
)env
->max_ga
);
1343 addInstr(env
, NANOMIPSInstr_XDirect(dst
, GuestStatePointer
,
1344 stmt
->Ist
.Exit
.offsIP
,
1347 HReg r
= newVRegI(env
);
1348 addInstr(env
, NANOMIPSInstr_Imm(NMimm_LI
, r
, INVALID_HREG
,
1350 addInstr(env
, NANOMIPSInstr_XAssisted(r
, GuestStatePointer
,
1351 stmt
->Ist
.Exit
.offsIP
,
1366 case Ijk_SigFPE_IntDiv
:
1367 case Ijk_SigFPE_IntOvf
:
1368 case Ijk_Sys_syscall
:
1369 case Ijk_InvalICache
: {
1370 HReg r
= newVRegI(env
);
1371 addInstr(env
, NANOMIPSInstr_Imm(NMimm_LI
, r
, INVALID_HREG
,
1373 vassert(stmt
->Ist
.Exit
.offsIP
>= 0);
1374 vassert(stmt
->Ist
.Exit
.offsIP
<= 0x1000);
1375 addInstr(env
, NANOMIPSInstr_XAssisted(r
, GuestStatePointer
,
1376 stmt
->Ist
.Exit
.offsIP
,
1377 cond
, stmt
->Ist
.Exit
.jk
));
1392 vex_printf("stmt_fail tag: 0x%x\n", stmt
->tag
);
1394 vpanic("iselStmt:\n");
1398 /*---------------------------------------------------------*/
1399 /*--- ISEL: Basic block terminators (Nexts) ---*/
1400 /*---------------------------------------------------------*/
1401 static void iselNext(ISelEnv
* env
,
1402 IRExpr
* next
, IRJumpKind jk
, Int offsIP
)
1404 if (vex_traceflags
& VEX_TRACE_VCODE
) {
1405 vex_printf( "\n-- PUT(%d) = ", offsIP
);
1407 vex_printf( "; exit-");
1412 /* Case: boring transfer to known address */
1413 if (next
->tag
== Iex_Const
) {
1414 IRConst
* cdst
= next
->Iex
.Const
.con
;
1415 vassert(cdst
->tag
== Ico_U32
);
1417 if (jk
== Ijk_Boring
|| jk
== Ijk_Call
) {
1418 vassert(offsIP
>= 0);
1419 vassert(offsIP
< 0x1000);
1421 /* Boring transfer to known address */
1422 if (env
->chainingAllowed
) {
1423 /* .. almost always true .. */
1424 /* Skip the event check at the dst if this is a forwards
1427 = (((Addr32
)cdst
->Ico
.U32
) > (Addr32
)env
->max_ga
);
1428 addInstr(env
, NANOMIPSInstr_XDirect((Addr
)cdst
->Ico
.U32
,
1429 GuestStatePointer
, offsIP
,
1430 INVALID_HREG
, toFastEP
));
1432 /* .. very occasionally .. */
1433 /* We can't use chaining, so ask for an assisted transfer,
1434 as that's the only alternative that is allowable. */
1435 HReg r
= iselWordExpr_R(env
, next
);
1436 addInstr(env
, NANOMIPSInstr_XAssisted(r
, GuestStatePointer
, offsIP
,
1437 INVALID_HREG
, Ijk_Boring
));
1444 /* Case: call/return (==boring) transfer to any address */
1449 HReg r
= iselWordExpr_R(env
, next
);
1450 vassert(offsIP
>= 0);
1451 vassert(offsIP
< 0x1000);
1453 if (env
->chainingAllowed
) {
1454 addInstr(env
, NANOMIPSInstr_XIndir(r
, GuestStatePointer
, offsIP
,
1457 addInstr(env
, NANOMIPSInstr_XAssisted(r
, GuestStatePointer
, offsIP
,
1458 INVALID_HREG
, Ijk_Boring
));
1468 /* Case: assisted transfer to arbitrary address */
1470 /* Keep this list in sync with that for Ist_Exit above */
1479 case Ijk_SigFPE_IntDiv
:
1480 case Ijk_SigFPE_IntOvf
:
1481 case Ijk_Sys_syscall
:
1482 case Ijk_InvalICache
: {
1483 HReg r
= iselWordExpr_R(env
, next
);
1484 vassert(offsIP
>= 0);
1485 vassert(offsIP
< 0x1000);
1486 addInstr(env
, NANOMIPSInstr_XAssisted(r
, GuestStatePointer
,
1487 offsIP
, INVALID_HREG
, jk
));
1495 vex_printf("\n-- PUT(%d) = ", offsIP
);
1497 vex_printf("; exit-");
1500 vassert(0); /* are we expecting any other kind? */
1503 /*---------------------------------------------------------*/
1504 /*--- Insn selector top-level ---*/
1505 /*---------------------------------------------------------*/
1507 /* Translate an entire BB to NANOMIPS code. */
1508 HInstrArray
*iselSB_NANOMIPS(const IRSB
* bb
,
1510 const VexArchInfo
* archinfo_host
,
1511 const VexAbiInfo
* vbi
,
1512 Int offs_Host_EvC_Counter
,
1513 Int offs_Host_EvC_FailAddr
,
1514 Bool chainingAllowed
,
1521 hwcaps_host
= archinfo_host
->hwcaps
;
1523 vassert(arch_host
== VexArchNANOMIPS
);
1524 /* Check that the host's endianness is as expected. */
1525 vassert(archinfo_host
->endness
== VexEndnessLE
1526 || archinfo_host
->endness
== VexEndnessBE
);
1527 /* Make up an initial environment to use. */
1528 env
= LibVEX_Alloc_inline(sizeof(ISelEnv
));
1530 /* Set up output code array. */
1531 env
->code
= newHInstrArray();
1532 /* Copy BB's type env. */
1533 env
->type_env
= bb
->tyenv
;
1534 /* Make up an IRTemp -> virtual HReg mapping. This doesn't
1535 change as we go along. */
1536 env
->n_vregmap
= bb
->tyenv
->types_used
;
1537 env
->vregmap
= LibVEX_Alloc_inline(env
->n_vregmap
* sizeof(HReg
));
1538 env
->vregmapHI
= LibVEX_Alloc_inline(env
->n_vregmap
* sizeof(HReg
));
1539 env
->hwcaps
= hwcaps_host
;
1540 env
->chainingAllowed
= chainingAllowed
;
1541 env
->max_ga
= max_ga
;
1542 /* For each IR temporary, allocate a suitably-kinded virtual
1546 for (i
= 0; i
< env
->n_vregmap
; i
++) {
1547 hregHI
= hreg
= INVALID_HREG
;
1549 switch (bb
->tyenv
->types
[i
]) {
1554 hreg
= mkHReg(True
, HRcInt32
, 0, j
++);
1558 hreg
= mkHReg(True
, HRcInt32
, 0, j
++);
1559 hregHI
= mkHReg(True
, HRcInt32
, 0, j
++);
1563 ppIRType(bb
->tyenv
->types
[i
]);
1564 vpanic("iselBB(nanomips): IRTemp type");
1568 env
->vregmap
[i
] = hreg
;
1569 env
->vregmapHI
[i
] = hregHI
;
1573 /* The very first instruction must be an event check. */
1574 vassert(offs_Host_EvC_Counter
>= 0);
1575 vassert(offs_Host_EvC_FailAddr
>= 0);
1576 vassert(offs_Host_EvC_Counter
< 0x1000);
1577 vassert(offs_Host_EvC_FailAddr
< 0x1000);
1578 addInstr(env
, NANOMIPSInstr_EvCheck(GuestStatePointer
,
1579 offs_Host_EvC_Counter
,
1581 offs_Host_EvC_FailAddr
));
1583 /* Possibly a block counter increment (for profiling). At this
1584 point we don't know the address of the counter, so just pretend
1585 it is zero. It will have to be patched later, but before this
1586 translation is used, by a call to LibVEX_patchProfCtr. */
1588 addInstr(env
, NANOMIPSInstr_ProfInc());
1591 /* Ok, finally we can iterate over the statements. */
1592 for (i
= 0; i
< bb
->stmts_used
; i
++)
1593 iselStmt(env
, bb
->stmts
[i
]);
1595 iselNext(env
, bb
->next
, bb
->jumpkind
, bb
->offsIP
);
1596 /* record the number of vregs we used. */
1597 env
->code
->n_vregs
= env
->vreg_ctr
;
1601 /*---------------------------------------------------------------*/
1602 /*--- end host_nanomips_isel.c ---*/
1603 /*---------------------------------------------------------------*/