1362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/*---------------------------------------------------------------*/
3362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/*--- begin                                  host_mips_defs.c ---*/
4362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/*---------------------------------------------------------------*/
5362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
6362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/*
7362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   This file is part of Valgrind, a dynamic binary instrumentation
8362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   framework.
9362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
10ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes   Copyright (C) 2010-2017 RT-RK
11362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      mips-valgrind@rt-rk.com
12362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
13362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   This program is free software; you can redistribute it and/or
14362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   modify it under the terms of the GNU General Public License as
15362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   published by the Free Software Foundation; either version 2 of the
16362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   License, or (at your option) any later version.
17362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
18362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   This program is distributed in the hope that it will be useful, but
19362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   WITHOUT ANY WARRANTY; without even the implied warranty of
20362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   General Public License for more details.
22362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
23362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   You should have received a copy of the GNU General Public License
24362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   along with this program; if not, write to the Free Software
25362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   02111-1307, USA.
27362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
28362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   The GNU General Public License is contained in the file COPYING.
29362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj*/
30362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
31362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj#include "libvex_basictypes.h"
32362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj#include "libvex.h"
33362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj#include "libvex_trc_values.h"
34362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
35362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj#include "main_util.h"
36362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj#include "host_generic_regs.h"
37362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj#include "host_mips_defs.h"
38362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
39b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj/* Register number for guest state pointer in host code. */
40b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj#define GuestSP 23
41b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
42b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
43362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/*---------------- Registers ----------------*/
44362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
45a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjconst RRegUniverse* getRRegUniverse_MIPS ( Bool mode64 )
46a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj{
47a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   /* The real-register universe is a big constant, so we just want to
48a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj      initialise it once.  rRegUniverse_MIPS_initted values: 0=not initted,
49a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj      1=initted for 32-bit-mode, 2=initted for 64-bit-mode */
50a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   static RRegUniverse rRegUniverse_MIPS;
51a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   static UInt         rRegUniverse_MIPS_initted = 0;
52a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj
53a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   /* Handy shorthand, nothing more */
54a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   RRegUniverse* ru = &rRegUniverse_MIPS;
55a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj
56a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   /* This isn't thread-safe.  Sigh. */
57a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   UInt howNeeded = mode64 ? 2 : 1;
58a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   if (LIKELY(rRegUniverse_MIPS_initted == howNeeded))
59a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj      return ru;
60a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj
61a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   RRegUniverse__init(ru);
62a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj
63a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   /* Add the registers.  The initial segment of this array must be
64a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj      those available for allocation by reg-alloc, and those that
65a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj      follow are not available for allocation. */
66a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR16(mode64);
67a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR17(mode64);
68a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR18(mode64);
69a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR19(mode64);
70a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR20(mode64);
71a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR21(mode64);
72a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR22(mode64);
73a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj
74a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR12(mode64);
75a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR13(mode64);
76a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR14(mode64);
77a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR15(mode64);
78a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR24(mode64);
79a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   /* s7  (=guest_state) */
80a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_F16(mode64);
81a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_F18(mode64);
82a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_F20(mode64);
83a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_F22(mode64);
84a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_F24(mode64);
85a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_F26(mode64);
86a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_F28(mode64);
87a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_F30(mode64);
88a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   if (!mode64) {
89a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj      /* Fake double floating point */
90a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj      ru->regs[ru->size++] = hregMIPS_D0(mode64);
91a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj      ru->regs[ru->size++] = hregMIPS_D1(mode64);
92a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj      ru->regs[ru->size++] = hregMIPS_D2(mode64);
93a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj      ru->regs[ru->size++] = hregMIPS_D3(mode64);
94a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj      ru->regs[ru->size++] = hregMIPS_D4(mode64);
95a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj      ru->regs[ru->size++] = hregMIPS_D5(mode64);
96a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj      ru->regs[ru->size++] = hregMIPS_D6(mode64);
97a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj      ru->regs[ru->size++] = hregMIPS_D7(mode64);
98a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   }
99a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj
100a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->allocable = ru->size;
101a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   /* And other regs, not available to the allocator. */
102a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj
103a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_HI(mode64);
104a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_LO(mode64);
105a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR0(mode64);
106a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR1(mode64);
107a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR2(mode64);
108a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR3(mode64);
109a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR4(mode64);
110a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR5(mode64);
111a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR6(mode64);
112a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR7(mode64);
113a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR8(mode64);
114a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR9(mode64);
115a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR10(mode64);
116a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR11(mode64);
117a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR23(mode64);
118a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR25(mode64);
119a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR29(mode64);
120a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   ru->regs[ru->size++] = hregMIPS_GPR31(mode64);
121a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj
122a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   rRegUniverse_MIPS_initted = howNeeded;
123a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj
124a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   RRegUniverse__check_is_sane(ru);
125a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   return ru;
126a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj}
127a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj
128a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj
129362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjvoid ppHRegMIPS(HReg reg, Bool mode64)
130362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
131362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   Int r;
13255085f8680acc89d727e321f3b34cae1a8c4093aflorian   static const HChar *ireg32_names[35]
133362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj       = { "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7",
134362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15",
135362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      "$16", "$17", "$18", "$19", "$20", "$21", "$22", "$23",
136362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      "$24", "$25", "$26", "$27", "$28", "$29", "$30", "$31",
137362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      "%32", "%33", "%34",
138362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   };
139362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
14055085f8680acc89d727e321f3b34cae1a8c4093aflorian   static const HChar *freg32_names[32]
141362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj       = { "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7",
142362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      "$f8", "$f9", "$f10", "$f11", "$f12", "$f13", "$f14", "$f15",
143362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      "$f16", "$f17", "$f18", "$f19", "$f20", "$f21", "$f22", "$f23",
144362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      "$f24", "$f25", "$f26", "$f27", "$f28", "$f29", "f30", "$f31"
145362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   };
146362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
14755085f8680acc89d727e321f3b34cae1a8c4093aflorian   static const HChar *freg64_names[32]
148362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj       = { "$d0", "$d1", "$d2", "$d3", "$d4", "$d5", "$d6", "$d7",
149362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      "$d8", "$d9", "$d10", "$d11", "$d12", "$d13", "$d14", "$d15",
150362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   };
151362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
152362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   /* Be generic for all virtual regs. */
153362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   if (hregIsVirtual(reg)) {
154362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      ppHReg(reg);
155362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      return;
156362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
157362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
158362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   /* But specific for real regs. */
159362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(hregClass(reg) == HRcInt32 || hregClass(reg) == HRcInt64 ||
1600e006f25d4016d7845bd016b65b5d2676a4e8c92dejanj           hregClass(reg) == HRcFlt32 || hregClass(reg) == HRcFlt64);
161362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
162362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   /* But specific for real regs. */
163b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   switch (hregClass(reg)) {
164b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case HRcInt32:
165a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         r = hregEncoding(reg);
166b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vassert(r >= 0 && r < 32);
167b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vex_printf("%s", ireg32_names[r]);
168b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         return;
169b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case HRcInt64:
170a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         r = hregEncoding (reg);
171b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vassert (r >= 0 && r < 32);
172b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vex_printf ("%s", ireg32_names[r]);
173b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         return;
174b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case HRcFlt32:
175a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         r = hregEncoding(reg);
176b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vassert(r >= 0 && r < 32);
177b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vex_printf("%s", freg32_names[r]);
178b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         return;
179b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case HRcFlt64:
180a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         r = hregEncoding(reg);
181b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vassert(r >= 0 && r < 32);
182b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vex_printf("%s", freg64_names[r]);
183b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         return;
184b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      default:
185b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vpanic("ppHRegMIPS");
186b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         break;
187362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
188362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
189362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return;
190362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
191362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
192362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
193362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/*----------------- Condition Codes ----------------------*/
194362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
19555085f8680acc89d727e321f3b34cae1a8c4093aflorianconst HChar *showMIPSCondCode(MIPSCondCode cond)
196362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
19755085f8680acc89d727e321f3b34cae1a8c4093aflorian   const HChar* ret;
198362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   switch (cond) {
199362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case MIPScc_EQ:
200b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = "EQ";  /* equal */
201362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
202362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case MIPScc_NE:
203b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = "NEQ";  /* not equal */
204362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
205362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case MIPScc_HS:
206b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = "GE";  /* >=u (Greater Than or Equal) */
207362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
208362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case MIPScc_LO:
209b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = "LT";  /* <u  (lower) */
210362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
211362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case MIPScc_MI:
212b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = "MI";  /* minus (negative) */
213362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
214362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case MIPScc_PL:
215b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = "PL";  /* plus (zero or +ve) */
216362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
217362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case MIPScc_VS:
218b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = "VS";  /* overflow */
219362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
220362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case MIPScc_VC:
221b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = "VC";  /* no overflow */
222362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
223362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case MIPScc_HI:
224b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = "HI";  /* >u   (higher) */
225362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
226362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case MIPScc_LS:
227b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = "LS";  /* <=u  (lower or same) */
228362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
229362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case MIPScc_GE:
230b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = "GE";  /* >=s (signed greater or equal) */
231362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
232362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case MIPScc_LT:
233b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = "LT";  /* <s  (signed less than) */
234362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
235362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case MIPScc_GT:
236b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = "GT";  /* >s  (signed greater) */
237362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
238362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case MIPScc_LE:
239b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = "LE";  /* <=s (signed less or equal) */
240362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
241362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case MIPScc_AL:
242b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = "AL";  /* always (unconditional) */
243362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
244362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case MIPScc_NV:
245b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = "NV";  /* never (unconditional): */
246362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
247362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      default:
248362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vpanic("showMIPSCondCode");
249362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
250362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
251362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return ret;
252362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
253362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
25455085f8680acc89d727e321f3b34cae1a8c4093aflorianconst HChar *showMIPSFpOp(MIPSFpOp op)
255362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
25655085f8680acc89d727e321f3b34cae1a8c4093aflorian   const HChar *ret;
257362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   switch (op) {
258362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_ADDD:
259c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "add.d";
260362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
261362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_SUBD:
262c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "sub.d";
263362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
264362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_MULD:
265c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "mul.d";
266362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
267362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_DIVD:
268c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "div.d";
269362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
270362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_MADDD:
271c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "madd.d";
272362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
273362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_MSUBD:
274c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "msub.d";
275362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
276362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_MADDS:
277c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "madd.s";
278362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
279362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_MSUBS:
280c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "msub.s";
281362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
282362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_ADDS:
283c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "add.s";
284362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
285362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_SUBS:
286c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "sub.s";
287362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
288362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_MULS:
289c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "mul.s";
290362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
291362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_DIVS:
292c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "div.s";
293362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
294362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_SQRTS:
295c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "sqrt.s";
296362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
297362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_SQRTD:
298c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "sqrt.d";
299362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
300362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_ABSS:
301c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "abs.s";
302362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
303362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_ABSD:
304c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "abs.d";
305362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
306362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_NEGS:
307c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "neg.s";
308362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
309362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_NEGD:
310c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "neg.d";
311362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
312362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_MOVS:
313c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "mov.s";
314362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
315362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_MOVD:
316c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "mov.d";
317362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
318362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_ROUNDWS:
319c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "round.w.s";
320362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
321362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_ROUNDWD:
322c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "round.w.d";
323362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
324a759d17f9b139ce17e9185291867fdeae3ad23efdejanj      case Mfp_ROUNDLD:
325a759d17f9b139ce17e9185291867fdeae3ad23efdejanj         ret = "round.l.d";
326a759d17f9b139ce17e9185291867fdeae3ad23efdejanj         break;
327362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_FLOORWS:
328c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "floor.w.s";
329362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
330362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_FLOORWD:
331c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "floor.w.d";
332362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
333362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_CVTDW:
334c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "cvt.d.w";
335b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         break;
336b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case Mfp_CVTDL:
337c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "cvt.d.l";
338b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         break;
339b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case Mfp_CVTDS:
340c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "cvt.d.s";
341362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
342362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_CVTSD:
343c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "cvt.s.d";
344c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         break;
345362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_CVTSW:
346c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "cvt.s.w";
347362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
348362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_CVTWS:
349c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "cvt.w.s";
350c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         break;
351362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_CVTWD:
352c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "cvt.w.d";
353362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
3540e006f25d4016d7845bd016b65b5d2676a4e8c92dejanj      case Mfp_CVTLD:
3550e006f25d4016d7845bd016b65b5d2676a4e8c92dejanj         ret = "cvt.l.d";
3560e006f25d4016d7845bd016b65b5d2676a4e8c92dejanj         break;
3570e006f25d4016d7845bd016b65b5d2676a4e8c92dejanj      case Mfp_CVTLS:
3580e006f25d4016d7845bd016b65b5d2676a4e8c92dejanj         ret = "cvt.l.s";
3590e006f25d4016d7845bd016b65b5d2676a4e8c92dejanj         break;
360362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_TRUWD:
361c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "trunc.w.d";
362c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         break;
363362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_TRUWS:
364c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "trunc.w.s";
365362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
366362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_TRULD:
367c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "trunc.l.d";
368c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         break;
369362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_TRULS:
370c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "trunc.l.s";
371362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
372362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_CEILWS:
373c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "ceil.w.s";
374c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         break;
375362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_CEILWD:
376c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "ceil.w.d";
377362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
378362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_CEILLS:
379c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "ceil.l.s";
380c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         break;
381362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mfp_CEILLD:
382c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = "ceil.l.d";
383362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
384f37c086134874a2ba372f6750a45466473a813b1dejanj      case Mfp_CMP_UN:
385f37c086134874a2ba372f6750a45466473a813b1dejanj         ret = "c.un.d";
386f37c086134874a2ba372f6750a45466473a813b1dejanj         break;
387f37c086134874a2ba372f6750a45466473a813b1dejanj      case Mfp_CMP_EQ:
388f37c086134874a2ba372f6750a45466473a813b1dejanj         ret = "c.eq.d";
389f37c086134874a2ba372f6750a45466473a813b1dejanj         break;
390f37c086134874a2ba372f6750a45466473a813b1dejanj      case Mfp_CMP_LT:
391f37c086134874a2ba372f6750a45466473a813b1dejanj         ret = "c.lt.d";
392f37c086134874a2ba372f6750a45466473a813b1dejanj         break;
393f37c086134874a2ba372f6750a45466473a813b1dejanj      case Mfp_CMP_NGT:
394f37c086134874a2ba372f6750a45466473a813b1dejanj         ret = "c.ngt.d";
395362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
396362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      default:
397b173774421d015736c2316b5e6e998e7de545a5cflorian         vex_printf("Unknown op: %d", (Int)op);
398362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vpanic("showMIPSFpOp");
399362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
400362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
401362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return ret;
402362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
403362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
404b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj/* Show move from/to fpr to/from gpr */
405b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarjconst HChar* showMIPSFpGpMoveOp ( MIPSFpGpMoveOp op )
406b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj{
407b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   const HChar *ret;
408b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   switch (op) {
409b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case MFpGpMove_mfc1:
410b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = "mfc1";
411b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         break;
412b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case MFpGpMove_dmfc1:
413b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = "dmfc1";
414b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         break;
415b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case MFpGpMove_mtc1:
416b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = "mtc1";
417b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         break;
418b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case MFpGpMove_dmtc1:
419b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = "dmtc1";
420b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         break;
421b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      default:
422b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vpanic("showMIPSFpGpMoveOp");
423b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         break;
424b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   }
425b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   return ret;
426b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj}
427b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
428b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj/* Show floating point move conditional */
429b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarjconst HChar* showMIPSMoveCondOp ( MIPSMoveCondOp op )
430b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj{
431b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   const HChar *ret;
432b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   switch (op) {
433b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case MFpMoveCond_movns:
434b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = "movn.s";
435b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         break;
436b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case MFpMoveCond_movnd:
437b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = "movn.d";
438b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         break;
439b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case MMoveCond_movn:
440b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = "movn";
441b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         break;
442b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      default:
443b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vpanic("showMIPSFpMoveCondOp");
444b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         break;
445b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   }
446b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   return ret;
447b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj}
448b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
449362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* --------- MIPSAMode: memory address expressions. --------- */
450362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
451362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSAMode *MIPSAMode_IR(Int idx, HReg base)
452362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
453d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSAMode *am = LibVEX_Alloc_inline(sizeof(MIPSAMode));
454362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   am->tag = Mam_IR;
455362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   am->Mam.IR.base = base;
456362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   am->Mam.IR.index = idx;
457362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
458362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return am;
459362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
460362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
461362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSAMode *MIPSAMode_RR(HReg idx, HReg base)
462362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
463d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSAMode *am = LibVEX_Alloc_inline(sizeof(MIPSAMode));
464362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   am->tag = Mam_RR;
465362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   am->Mam.RR.base = base;
466362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   am->Mam.RR.index = idx;
467362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
468362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return am;
469362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
470362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
471362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSAMode *dopyMIPSAMode(MIPSAMode * am)
472362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
473362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   MIPSAMode* ret;
474362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   switch (am->tag) {
475362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mam_IR:
476362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ret = MIPSAMode_IR(am->Mam.IR.index, am->Mam.IR.base);
477362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
478362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mam_RR:
479362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ret = MIPSAMode_RR(am->Mam.RR.index, am->Mam.RR.base);
480362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
481362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      default:
482362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vpanic("dopyMIPSAMode");
483362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
484362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
485362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return ret;
486362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
487362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
488362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSAMode *nextMIPSAModeFloat(MIPSAMode * am)
489362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
490362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   MIPSAMode* ret;
491362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   switch (am->tag) {
492362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mam_IR:
4931ec43e09fe3d870c3dfd3d1f4eb8198cbaf91370petarj         ret = MIPSAMode_IR(am->Mam.IR.index + 4, am->Mam.IR.base);
494362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
495362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mam_RR:
496a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         /* We can't do anything with the RR case, so if it appears
497a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj            we simply have to give up. */
498a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         /* fallthrough */
499362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      default:
500a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         vpanic("nextMIPSAModeFloat");
501362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
502362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
503362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return ret;
504362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
505362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
506362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSAMode *nextMIPSAModeInt(MIPSAMode * am)
507362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
508362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   MIPSAMode* ret;
509362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   switch (am->tag) {
510362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mam_IR:
511362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ret = MIPSAMode_IR(am->Mam.IR.index + 4, am->Mam.IR.base);
512362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
513362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mam_RR:
514a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         /* We can't do anything with the RR case, so if it appears
515a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj            we simply have to give up. */
516a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         /* fallthrough */
517362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      default:
518a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj         vpanic("nextMIPSAModeInt");
519362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
520362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
521362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return ret;
522362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
523362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
524362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjvoid ppMIPSAMode(MIPSAMode * am, Bool mode64)
525362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
526362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   switch (am->tag) {
527362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mam_IR:
528362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         if (am->Mam.IR.index == 0)
529362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            vex_printf("0(");
530362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         else
531362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            vex_printf("%d(", (Int) am->Mam.IR.index);
532362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(am->Mam.IR.base, mode64);
533362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(")");
534362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
535362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mam_RR:
536362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(am->Mam.RR.base, mode64);
537362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(", ");
538362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(am->Mam.RR.index, mode64);
539362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
540362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      default:
541362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vpanic("ppMIPSAMode");
542362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
543362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
544362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
545362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
546362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjstatic void addRegUsage_MIPSAMode(HRegUsage * u, MIPSAMode * am)
547362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
548362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   switch (am->tag) {
549362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mam_IR:
550362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, am->Mam.IR.base);
551362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
552362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mam_RR:
553362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, am->Mam.RR.base);
554362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, am->Mam.RR.index);
555362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
556362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      default:
557362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vpanic("addRegUsage_MIPSAMode");
558362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
559362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
560362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
561362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
562362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjstatic void mapRegs_MIPSAMode(HRegRemap * m, MIPSAMode * am)
563362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
564362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   switch (am->tag) {
565362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mam_IR:
566362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         am->Mam.IR.base = lookupHRegRemap(m, am->Mam.IR.base);
567362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
568362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mam_RR:
569362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         am->Mam.RR.base = lookupHRegRemap(m, am->Mam.RR.base);
570362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         am->Mam.RR.index = lookupHRegRemap(m, am->Mam.RR.index);
571362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
572362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      default:
573362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vpanic("mapRegs_MIPSAMode");
574362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
575362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
576362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
577362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
578362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* --------- Operand, which can be a reg or a u16/s16. --------- */
579362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
580362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSRH *MIPSRH_Imm(Bool syned, UShort imm16)
581362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
582d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSRH *op = LibVEX_Alloc_inline(sizeof(MIPSRH));
583362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   op->tag = Mrh_Imm;
584362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   op->Mrh.Imm.syned = syned;
585362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   op->Mrh.Imm.imm16 = imm16;
586362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   /* If this is a signed value, ensure it's not -32768, so that we
587362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      are guaranteed always to be able to negate if needed. */
588362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   if (syned)
589362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      vassert(imm16 != 0x8000);
590362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(syned == True || syned == False);
591362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return op;
592362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
593362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
594362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSRH *MIPSRH_Reg(HReg reg)
595362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
596d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSRH *op = LibVEX_Alloc_inline(sizeof(MIPSRH));
597362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   op->tag = Mrh_Reg;
598362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   op->Mrh.Reg.reg = reg;
599362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return op;
600362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
601362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
602362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjvoid ppMIPSRH(MIPSRH * op, Bool mode64)
603362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
604362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   MIPSRHTag tag = op->tag;
605362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   switch (tag) {
606362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mrh_Imm:
607362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         if (op->Mrh.Imm.syned)
608362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            vex_printf("%d", (Int) (Short) op->Mrh.Imm.imm16);
609362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         else
610362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            vex_printf("%u", (UInt) (UShort) op->Mrh.Imm.imm16);
611362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
612362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mrh_Reg:
613362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(op->Mrh.Reg.reg, mode64);
614362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
615362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      default:
616362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vpanic("ppMIPSRH");
617362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
618362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
619362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
620362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
621362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* An MIPSRH can only be used in a "read" context (what would it mean
622362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   to write or modify a literal?) and so we enumerate its registers
623362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   accordingly. */
624362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjstatic void addRegUsage_MIPSRH(HRegUsage * u, MIPSRH * op)
625362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
626362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   switch (op->tag) {
627362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mrh_Imm:
628362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
629362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mrh_Reg:
630362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, op->Mrh.Reg.reg);
631362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
632362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      default:
633362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vpanic("addRegUsage_MIPSRH");
634362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
635362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
636362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
637362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
638362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjstatic void mapRegs_MIPSRH(HRegRemap * m, MIPSRH * op)
639362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
640362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   switch (op->tag) {
641362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mrh_Imm:
642362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
643362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mrh_Reg:
644362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         op->Mrh.Reg.reg = lookupHRegRemap(m, op->Mrh.Reg.reg);
645362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
646362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      default:
647362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vpanic("mapRegs_MIPSRH");
648362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
649362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
650362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
651362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
652362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* --------- Instructions. --------- */
653362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
65455085f8680acc89d727e321f3b34cae1a8c4093aflorianconst HChar *showMIPSUnaryOp(MIPSUnaryOp op)
655362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
65655085f8680acc89d727e321f3b34cae1a8c4093aflorian   const HChar* ret;
657362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   switch (op) {
658362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mun_CLO:
659362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ret = "clo";
660362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
661362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mun_CLZ:
662362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ret = "clz";
663362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
664362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mun_NOP:
665362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ret = "nop";
666362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
667b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case Mun_DCLO:
668b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = "dclo";
669b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         break;
670b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case Mun_DCLZ:
671b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = "dclz";
672b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         break;
673362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      default:
674362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vpanic("showMIPSUnaryOp");
675362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
676362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
677362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return ret;
678362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
679362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
68055085f8680acc89d727e321f3b34cae1a8c4093aflorianconst HChar *showMIPSAluOp(MIPSAluOp op, Bool immR)
681362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
68255085f8680acc89d727e321f3b34cae1a8c4093aflorian   const HChar* ret;
683362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   switch (op) {
684362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Malu_ADD:
685362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ret = immR ? "addiu" : "addu";
686362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
687362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Malu_SUB:
688362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ret = "subu";
689362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
690362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Malu_AND:
691362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ret = immR ? "andi" : "and";
692362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
693362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Malu_OR:
694362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ret = immR ? "ori" : "or";
695362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
696362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Malu_NOR:
697362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vassert(immR == False); /*there's no nor with an immediate operand!? */
698362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ret = "nor";
699362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
700362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Malu_XOR:
701362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ret = immR ? "xori" : "xor";
702362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
703b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case Malu_DADD:
704b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = immR ? "daddi" : "dadd";
705b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         break;
706b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case Malu_DSUB:
707b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = immR ? "dsubi" : "dsub";
708b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         break;
709b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case Malu_SLT:
710b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ret = immR ? "slti" : "slt";
711b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         break;
712362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      default:
713362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vpanic("showMIPSAluOp");
714362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
715362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
716362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return ret;
717362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
718362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
71955085f8680acc89d727e321f3b34cae1a8c4093aflorianconst HChar *showMIPSShftOp(MIPSShftOp op, Bool immR, Bool sz32)
720362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
72155085f8680acc89d727e321f3b34cae1a8c4093aflorian   const HChar *ret;
722362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   switch (op) {
723362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mshft_SRA:
724c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         ret = immR ? (sz32 ? "sra" : "dsra") : (sz32 ? "srav" : "dsrav");
725362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
726362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mshft_SLL:
727362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ret = immR ? (sz32 ? "sll" : "dsll") : (sz32 ? "sllv" : "dsllv");
728362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
729362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Mshft_SRL:
730362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ret = immR ? (sz32 ? "srl" : "dsrl") : (sz32 ? "srlv" : "dsrlv");
731362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
732362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      default:
733362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vpanic("showMIPSShftOp");
734362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
735362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
736362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return ret;
737362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
738362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
73955085f8680acc89d727e321f3b34cae1a8c4093aflorianconst HChar *showMIPSMaccOp(MIPSMaccOp op, Bool variable)
740362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
74155085f8680acc89d727e321f3b34cae1a8c4093aflorian   const HChar *ret;
742362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   switch (op) {
743362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Macc_ADD:
744362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ret = variable ? "madd" : "maddu";
745362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
746362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Macc_SUB:
747362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ret = variable ? "msub" : "msubu";
748362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
749362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      default:
750362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vpanic("showMIPSAccOp");
751362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
752362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
753362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return ret;
754362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
755362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
756362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_LI(HReg dst, ULong imm)
757362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
758d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
759362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_LI;
760362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.LI.dst = dst;
761362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.LI.imm = imm;
762362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
763362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
764362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
765362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_Alu(MIPSAluOp op, HReg dst, HReg srcL, MIPSRH * srcR)
766362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
767d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
768362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_Alu;
769362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Alu.op = op;
770362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Alu.dst = dst;
771362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Alu.srcL = srcL;
772362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Alu.srcR = srcR;
773362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
774362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
775362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
776362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_Shft(MIPSShftOp op, Bool sz32, HReg dst, HReg srcL,
777362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                          MIPSRH * srcR)
778362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
779d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
780362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_Shft;
781362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Shft.op = op;
782362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Shft.sz32 = sz32;
783362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Shft.dst = dst;
784362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Shft.srcL = srcL;
785362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Shft.srcR = srcR;
786362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
787362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
788362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
789362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_Unary(MIPSUnaryOp op, HReg dst, HReg src)
790362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
791d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
792362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_Unary;
793362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Unary.op = op;
794362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Unary.dst = dst;
795362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Unary.src = src;
796362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
797362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
798362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
799362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_Cmp(Bool syned, Bool sz32, HReg dst, HReg srcL, HReg srcR,
800362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                         MIPSCondCode cond)
801362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
802d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
803362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_Cmp;
804362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Cmp.syned = syned;
805362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Cmp.sz32 = sz32;
806362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Cmp.dst = dst;
807362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Cmp.srcL = srcL;
808362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Cmp.srcR = srcR;
809362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Cmp.cond = cond;
810362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
811362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
812362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
813362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* multiply */
814362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_Mul(Bool syned, Bool wid, Bool sz32, HReg dst, HReg srcL,
815362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                         HReg srcR)
816362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
817d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
818362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_Mul;
819362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Mul.syned = syned;
820362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Mul.widening = wid; /* widen=True else False */
821362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Mul.sz32 = sz32; /* True = 32 bits */
822362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Mul.dst = dst;
823362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Mul.srcL = srcL;
824362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Mul.srcR = srcR;
825362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
826362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
827362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
828362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* msub */
829362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_Msub(Bool syned, HReg srcL, HReg srcR)
830362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
831d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
832362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_Macc;
833362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
834362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Macc.op = Macc_SUB;
835362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Macc.syned = syned;
836362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Macc.srcL = srcL;
837362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Macc.srcR = srcR;
838362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
839362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
840362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
841362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* madd */
842362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_Madd(Bool syned, HReg srcL, HReg srcR)
843362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
844d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
845362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_Macc;
846362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
847362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Macc.op = Macc_ADD;
848362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Macc.syned = syned;
849362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Macc.srcL = srcL;
850362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Macc.srcR = srcR;
851362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
852362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
853362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
854362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* div */
855362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_Div(Bool syned, Bool sz32, HReg srcL, HReg srcR)
856362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
857d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
858362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_Div;
859362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Div.syned = syned;
860362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Div.sz32 = sz32; /* True = 32 bits */
861362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Div.srcL = srcL;
862362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Div.srcR = srcR;
863362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
864362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
865362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
866b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarjMIPSInstr *MIPSInstr_Call ( MIPSCondCode cond, Addr64 target, UInt argiregs,
867b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                            HReg src, RetLoc rloc )
868362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
869362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   UInt mask;
870d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
871362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_Call;
872362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Call.cond = cond;
873362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Call.target = target;
874362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Call.argiregs = argiregs;
875362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Call.src = src;
876cfe046e178666280b87da998b1b52ecda03ecd89sewardj   i->Min.Call.rloc = rloc;
877b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   /* Only $4 .. $7/$11 inclusive may be used as arg regs. */
878b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   mask = (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9)
879b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj          | (1 << 10) | (1 << 11);
880362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(0 == (argiregs & ~mask));
88174142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   vassert(is_sane_RetLoc(rloc));
882362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
883362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
884362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
885b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarjMIPSInstr *MIPSInstr_CallAlways ( MIPSCondCode cond, Addr64 target,
886b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                                  UInt argiregs, RetLoc rloc )
887362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
888362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   UInt mask;
889d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
890362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_Call;
891362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Call.cond = cond;
892362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Call.target = target;
893362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Call.argiregs = argiregs;
894cfe046e178666280b87da998b1b52ecda03ecd89sewardj   i->Min.Call.rloc = rloc;
895b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   /* Only $4 .. $7/$11 inclusive may be used as arg regs. */
896b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   mask = (1 << 4) | (1 << 5) | (1 << 6) | (1 << 7) | (1 << 8) | (1 << 9)
897b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj          | (1 << 10) | (1 << 11);
898362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(0 == (argiregs & ~mask));
89974142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj   vassert(is_sane_RetLoc(rloc));
900362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
901362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
902362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
903b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarjMIPSInstr *MIPSInstr_XDirect ( Addr64 dstGA, MIPSAMode* amPC,
904362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                               MIPSCondCode cond, Bool toFastEP ) {
905d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr* i               = LibVEX_Alloc_inline(sizeof(MIPSInstr));
906362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag                     = Min_XDirect;
907362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.XDirect.dstGA       = dstGA;
908362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.XDirect.amPC        = amPC;
909362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.XDirect.cond        = cond;
910362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.XDirect.toFastEP    = toFastEP;
911362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
912362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
913362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
914362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_XIndir ( HReg dstGA, MIPSAMode* amPC,
915362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                              MIPSCondCode cond ) {
916d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr* i            = LibVEX_Alloc_inline(sizeof(MIPSInstr));
917362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag                  = Min_XIndir;
918362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.XIndir.dstGA     = dstGA;
919362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.XIndir.amPC      = amPC;
920362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.XIndir.cond      = cond;
921362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
922362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
923362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
924362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_XAssisted ( HReg dstGA, MIPSAMode* amPC,
925362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                                 MIPSCondCode cond, IRJumpKind jk ) {
926d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr* i               = LibVEX_Alloc_inline(sizeof(MIPSInstr));
927362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag                     = Min_XAssisted;
928362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.XAssisted.dstGA     = dstGA;
929362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.XAssisted.amPC      = amPC;
930362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.XAssisted.cond      = cond;
931362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.XAssisted.jk        = jk;
932362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
933362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
934362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
935362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_Load(UChar sz, HReg dst, MIPSAMode * src, Bool mode64)
936362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
937d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
938362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_Load;
939362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Load.sz = sz;
940362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Load.src = src;
941362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Load.dst = dst;
942362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(sz == 1 || sz == 2 || sz == 4 || sz == 8);
943362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
944362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   if (sz == 8)
945362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      vassert(mode64);
946362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
947362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
948362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
949362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_Store(UChar sz, MIPSAMode * dst, HReg src, Bool mode64)
950362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
951d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
952362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_Store;
953362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Store.sz = sz;
954362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Store.src = src;
955362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.Store.dst = dst;
956362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(sz == 1 || sz == 2 || sz == 4 || sz == 8);
957362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
958362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   if (sz == 8)
959362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      vassert(mode64);
960362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
961362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
962362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
963362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_LoadL(UChar sz, HReg dst, MIPSAMode * src, Bool mode64)
964362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
965d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
966362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_LoadL;
967362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.LoadL.sz  = sz;
968362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.LoadL.src = src;
969362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.LoadL.dst = dst;
970362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(sz == 4 || sz == 8);
971362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
972362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   if (sz == 8)
973362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      vassert(mode64);
974362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
975362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
976362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
9776ced72b3286a45a9fd05989a1e13c0ac5b911feedejanjMIPSInstr *MIPSInstr_Cas(UChar sz, HReg old, HReg addr,
9786ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj                         HReg expd, HReg data, Bool mode64)
9796ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj{
980d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i    = LibVEX_Alloc_inline(sizeof(MIPSInstr));
9816ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj   i->tag          = Min_Cas;
9826ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj   i->Min.Cas.sz   = sz;
9836ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj   i->Min.Cas.old  = old;
9846ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj   i->Min.Cas.addr = addr;
9856ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj   i->Min.Cas.expd = expd;
9866ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj   i->Min.Cas.data = data;
9876ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj   vassert(sz == 1 || sz == 2 || sz == 4 || sz == 8);
9886ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj
9896ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj   if (sz == 8)
9906ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj      vassert(mode64);
9916ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj   return i;
9926ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj}
9936ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj
994362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_StoreC(UChar sz, MIPSAMode * dst, HReg src, Bool mode64)
995362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
996d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
997362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_StoreC;
998362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.StoreC.sz  = sz;
999362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.StoreC.src = src;
1000362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.StoreC.dst = dst;
1001362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(sz == 4 || sz == 8);
1002362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1003362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   if (sz == 8)
1004362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      vassert(mode64);
1005362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
1006362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
1007362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1008362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_Mthi(HReg src)
1009362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
1010d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
1011362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_Mthi;
1012362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.MtHL.src = src;
1013362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
1014362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
1015362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1016362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_Mtlo(HReg src)
1017362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
1018d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
1019362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_Mtlo;
1020362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.MtHL.src = src;
1021362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
1022362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
1023362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1024362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_Mfhi(HReg dst)
1025362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
1026d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
1027362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_Mfhi;
1028362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.MfHL.dst = dst;
1029362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
1030362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
1031362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1032362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_Mflo(HReg dst)
1033362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
1034d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
1035362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_Mflo;
1036362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.MfHL.dst = dst;
1037362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
1038362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
1039362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1040362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* Read/Write Link Register */
1041362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_RdWrLR(Bool wrLR, HReg gpr)
1042362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
1043d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
1044362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_RdWrLR;
1045362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.RdWrLR.wrLR = wrLR;
1046362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.RdWrLR.gpr = gpr;
1047362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
1048362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
1049362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1050362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_FpLdSt(Bool isLoad, UChar sz, HReg reg, MIPSAMode * addr)
1051362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
1052d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
1053362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_FpLdSt;
1054362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.FpLdSt.isLoad = isLoad;
1055362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.FpLdSt.sz = sz;
1056362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.FpLdSt.reg = reg;
1057362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.FpLdSt.addr = addr;
1058362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(sz == 4 || sz == 8);
1059362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
1060362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
1061362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1062362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_FpUnary(MIPSFpOp op, HReg dst, HReg src)
1063362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
1064d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
1065362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_FpUnary;
1066362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.FpUnary.op = op;
1067362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.FpUnary.dst = dst;
1068362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.FpUnary.src = src;
1069362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
1070362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
1071362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1072362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_FpBinary(MIPSFpOp op, HReg dst, HReg srcL, HReg srcR)
1073362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
1074d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
1075362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_FpBinary;
1076362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.FpBinary.op = op;
1077362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.FpBinary.dst = dst;
1078362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.FpBinary.srcL = srcL;
1079362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.FpBinary.srcR = srcR;
1080362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
1081362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
1082362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1083b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarjMIPSInstr *MIPSInstr_FpTernary ( MIPSFpOp op, HReg dst, HReg src1, HReg src2,
1084b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                                 HReg src3 )
1085b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj{
1086d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
1087b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   i->tag = Min_FpTernary;
1088b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   i->Min.FpTernary.op = op;
1089b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   i->Min.FpTernary.dst = dst;
1090b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   i->Min.FpTernary.src1 = src1;
1091b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   i->Min.FpTernary.src2 = src2;
1092b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   i->Min.FpTernary.src3 = src3;
1093b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   return i;
1094b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj}
1095b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
1096362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_FpConvert(MIPSFpOp op, HReg dst, HReg src)
1097362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
1098d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
1099362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_FpConvert;
1100362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.FpConvert.op = op;
1101362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.FpConvert.dst = dst;
1102362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.FpConvert.src = src;
1103362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
1104362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1105362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
1106362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1107f37c086134874a2ba372f6750a45466473a813b1dejanjMIPSInstr *MIPSInstr_FpCompare(MIPSFpOp op, HReg dst, HReg srcL, HReg srcR)
1108362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
1109d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
1110362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_FpCompare;
1111362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.FpCompare.op = op;
1112362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.FpCompare.dst = dst;
1113362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.FpCompare.srcL = srcL;
1114362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.FpCompare.srcR = srcR;
1115362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
1116362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
1117362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1118362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_MtFCSR(HReg src)
1119362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
1120d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
1121362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_MtFCSR;
1122362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.MtFCSR.src = src;
1123362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
1124362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
1125362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1126362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_MfFCSR(HReg dst)
1127362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
1128d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
1129362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag = Min_MfFCSR;
1130362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.MfFCSR.dst = dst;
1131362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
1132362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
1133362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1134b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarjMIPSInstr *MIPSInstr_FpGpMove ( MIPSFpGpMoveOp op, HReg dst, HReg src )
1135b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj{
1136d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i        = LibVEX_Alloc_inline(sizeof(MIPSInstr));
1137b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   i->tag              = Min_FpGpMove;
1138b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   i->Min.FpGpMove.op  = op;
1139b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   i->Min.FpGpMove.dst = dst;
1140b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   i->Min.FpGpMove.src = src;
1141b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   return i;
1142b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj}
1143b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
1144b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarjMIPSInstr *MIPSInstr_MoveCond ( MIPSMoveCondOp op, HReg dst, HReg src,
1145b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                                HReg cond )
1146b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj{
1147d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr *i        = LibVEX_Alloc_inline(sizeof(MIPSInstr));
1148b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   i->tag              = Min_MoveCond;
1149b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   i->Min.MoveCond.op  = op;
1150b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   i->Min.MoveCond.dst = dst;
1151b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   i->Min.MoveCond.src = src;
1152b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   i->Min.MoveCond.cond = cond;
1153b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   return i;
1154b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj}
1155b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
1156362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr *MIPSInstr_EvCheck ( MIPSAMode* amCounter,
1157362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                            MIPSAMode* amFailAddr ) {
1158d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr* i                 = LibVEX_Alloc_inline(sizeof(MIPSInstr));
1159362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag                       = Min_EvCheck;
1160362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.EvCheck.amCounter     = amCounter;
1161362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->Min.EvCheck.amFailAddr    = amFailAddr;
1162362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
1163362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
1164362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1165362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjMIPSInstr* MIPSInstr_ProfInc ( void ) {
1166d8e3ecaede8eccf5bc7be2a55d99a188a07b0a34florian   MIPSInstr* i = LibVEX_Alloc_inline(sizeof(MIPSInstr));
1167362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   i->tag       = Min_ProfInc;
1168362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return i;
1169362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
1170362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1171362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* -------- Pretty Print instructions ------------- */
1172362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjstatic void ppLoadImm(HReg dst, ULong imm, Bool mode64)
1173362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
1174362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vex_printf("li ");
1175362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   ppHRegMIPS(dst, mode64);
1176362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vex_printf(",0x%016llx", imm);
1177362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
1178362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1179d8c64e082224b2e688abdef9219cc76fd82b373bflorianvoid ppMIPSInstr(const MIPSInstr * i, Bool mode64)
1180362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
1181362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   switch (i->tag) {
1182362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_LI:
1183362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppLoadImm(i->Min.LI.dst, i->Min.LI.imm, mode64);
1184362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
1185362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Alu: {
1186362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         HReg r_srcL = i->Min.Alu.srcL;
1187362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         MIPSRH *rh_srcR = i->Min.Alu.srcR;
1188362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* generic */
1189362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("%s ", showMIPSAluOp(i->Min.Alu.op,
1190362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                                         toBool(rh_srcR->tag == Mrh_Imm)));
1191362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.Alu.dst, mode64);
1192362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(",");
1193362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(r_srcL, mode64);
1194362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(",");
1195362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppMIPSRH(rh_srcR, mode64);
1196362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1197362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
1198362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Shft: {
1199362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         HReg r_srcL = i->Min.Shft.srcL;
1200362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         MIPSRH *rh_srcR = i->Min.Shft.srcR;
1201362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("%s ", showMIPSShftOp(i->Min.Shft.op,
1202362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                                          toBool(rh_srcR->tag == Mrh_Imm),
1203362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                                          i->Min.Shft.sz32));
1204362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.Shft.dst, mode64);
1205362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(",");
1206362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(r_srcL, mode64);
1207362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(",");
1208362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppMIPSRH(rh_srcR, mode64);
1209362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1210362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
1211362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Unary: {
1212362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("%s ", showMIPSUnaryOp(i->Min.Unary.op));
1213362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.Unary.dst, mode64);
1214362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(",");
1215362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.Unary.src, mode64);
1216362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1217362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
1218362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Cmp: {
1219362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("word_compare ");
1220362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.Cmp.dst, mode64);
1221362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(" = %s ( ", showMIPSCondCode(i->Min.Cmp.cond));
1222362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.Cmp.srcL, mode64);
1223362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(", ");
1224362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.Cmp.srcR, mode64);
1225362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(" )");
1226362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1227362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1228362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
1229362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Mul: {
1230362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         switch (i->Min.Mul.widening) {
1231362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case False:
1232362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               vex_printf("mul ");
1233362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               ppHRegMIPS(i->Min.Mul.dst, mode64);
1234362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               vex_printf(", ");
1235362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               ppHRegMIPS(i->Min.Mul.srcL, mode64);
1236362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               vex_printf(", ");
1237362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               ppHRegMIPS(i->Min.Mul.srcR, mode64);
1238362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               return;
1239362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case True:
1240362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               vex_printf("%s%s ", i->Min.Mul.sz32 ? "mult" : "dmult",
1241362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                                   i->Min.Mul.syned ? "" : "u");
1242362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               ppHRegMIPS(i->Min.Mul.dst, mode64);
1243362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               vex_printf(", ");
1244362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               ppHRegMIPS(i->Min.Mul.srcL, mode64);
1245362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               vex_printf(", ");
1246362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               ppHRegMIPS(i->Min.Mul.srcR, mode64);
1247362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               return;
1248362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
1249362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
1250362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
1251362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Mthi: {
1252362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("mthi ");
1253362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.MtHL.src, mode64);
1254362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1255362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
1256362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Mtlo: {
1257362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("mtlo ");
1258362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.MtHL.src, mode64);
1259362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1260362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
1261362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Mfhi: {
1262362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("mfhi ");
1263362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.MfHL.dst, mode64);
1264362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1265362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
1266362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Mflo: {
1267362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("mflo ");
1268362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.MfHL.dst, mode64);
1269362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1270362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
1271362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Macc: {
1272362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("%s ", showMIPSMaccOp(i->Min.Macc.op, i->Min.Macc.syned));
1273362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.Macc.srcL, mode64);
1274362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(", ");
1275362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.Macc.srcR, mode64);
1276362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1277362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
1278362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Div: {
1279362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         if (!i->Min.Div.sz32)
1280362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            vex_printf("d");
1281362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("div");
1282362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("%s ", i->Min.Div.syned ? "s" : "u");
1283362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.Div.srcL, mode64);
1284362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(", ");
1285362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.Div.srcR, mode64);
1286362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1287362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
1288362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Call: {
1289362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         Int n;
1290362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("call: ");
1291362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         if (i->Min.Call.cond != MIPScc_AL) {
1292362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            vex_printf("if (%s) ", showMIPSCondCode(i->Min.Call.cond));
1293362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
1294b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vex_printf(" {");
1295b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         if (!mode64)
1296b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            vex_printf(" addiu $29, $29, -16");
1297362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1298b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ppLoadImm(hregMIPS_GPR25(mode64), i->Min.Call.target, mode64);
1299b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
1300b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vex_printf(" ; jarl $31, $25; # args [");
1301362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         for (n = 0; n < 32; n++) {
1302362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            if (i->Min.Call.argiregs & (1 << n)) {
1303b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               vex_printf("$%d", n);
1304362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               if ((i->Min.Call.argiregs >> n) > 1)
1305362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  vex_printf(",");
1306362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
1307362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
1308b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vex_printf("] nop; ");
1309b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         if (!mode64)
1310b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            vex_printf("addiu $29, $29, 16; ]");
1311b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
1312362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
1313362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
1314362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_XDirect:
1315362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("(xDirect) ");
1316362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("if (guest_COND.%s) { ",
1317362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                    showMIPSCondCode(i->Min.XDirect.cond));
1318b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vex_printf("move $9, 0x%x,", (UInt)i->Min.XDirect.dstGA);
1319362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("; sw $9, ");
1320362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppMIPSAMode(i->Min.XDirect.amPC, mode64);
1321362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("; move $9, $disp_cp_chain_me_to_%sEP; jalr $9; nop}",
1322362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                    i->Min.XDirect.toFastEP ? "fast" : "slow");
1323362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1324362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_XIndir:
1325362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("(xIndir) ");
1326362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("if (guest_COND.%s) { sw ",
1327c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj                    showMIPSCondCode(i->Min.XIndir.cond));
1328362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.XIndir.dstGA, mode64);
1329362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(", ");
1330362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppMIPSAMode(i->Min.XIndir.amPC, mode64);
1331362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("; move $9, $disp_indir; jalr $9; nop}");
1332362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1333362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_XAssisted:
1334362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("(xAssisted) ");
1335362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("if (guest_COND.%s) { ",
1336362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                    showMIPSCondCode(i->Min.XAssisted.cond));
1337362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("sw ");
1338362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.XAssisted.dstGA, mode64);
1339362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(", ");
1340362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppMIPSAMode(i->Min.XAssisted.amPC, mode64);
1341362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("; move $9, $IRJumpKind_to_TRCVAL(%d)",
1342362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                    (Int)i->Min.XAssisted.jk);
1343362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("; move $9, $disp_assisted; jalr $9; nop; }");
1344362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1345362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Load: {
1346362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         Bool idxd = toBool(i->Min.Load.src->tag == Mam_RR);
1347362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UChar sz = i->Min.Load.sz;
13485df8ab0739ec95e8de9d9f43fa0e68b3e7125554florian         HChar c_sz = sz == 1 ? 'b' : sz == 2 ? 'h' : sz == 4 ? 'w' : 'd';
1349362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("l%c%s ", c_sz, idxd ? "x" : "");
1350362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.Load.dst, mode64);
1351362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(",");
1352362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppMIPSAMode(i->Min.Load.src, mode64);
1353362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1354362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
1355362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Store: {
1356362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UChar sz = i->Min.Store.sz;
1357362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         Bool idxd = toBool(i->Min.Store.dst->tag == Mam_RR);
13585df8ab0739ec95e8de9d9f43fa0e68b3e7125554florian         HChar c_sz = sz == 1 ? 'b' : sz == 2 ? 'h' : sz == 4 ? 'w' : 'd';
1359362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("s%c%s ", c_sz, idxd ? "x" : "");
1360362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.Store.src, mode64);
1361362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(",");
1362362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppMIPSAMode(i->Min.Store.dst, mode64);
1363362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1364362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
1365362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_LoadL: {
1366362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("ll ");
1367362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.LoadL.dst, mode64);
1368362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(",");
1369362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppMIPSAMode(i->Min.LoadL.src, mode64);
1370362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1371362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
13726ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj      case Min_Cas: {
13736ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj          Bool sz8  = toBool(i->Min.Cas.sz == 8);
13746ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj          /*
13756ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj           * ll(d)    old,  0(addr)
13766ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj           * bne      old,  expd, end
13776ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj           * nop
13786ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj           * (d)addiu old,  old,  1
13796ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj           * sc(d)    data, 0(addr)
13806ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj           * movn     old,  expd, data
13816ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj           * end:
13826ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj           */
13836ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj          // ll(d) old, 0(addr)
13846ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         vex_printf("cas: ");
13856ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj
13866ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         vex_printf("%s ", sz8 ? "lld" : "ll");
13876ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         ppHRegMIPS(i->Min.Cas.old , mode64);
13886ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         vex_printf(", 0(");
13896ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         ppHRegMIPS(i->Min.Cas.addr , mode64);
13906ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         vex_printf(")\n");
13916ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj
13926ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         vex_printf("bne ");
13936ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         ppHRegMIPS(i->Min.Cas.old , mode64);
13946ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         vex_printf(", ");
13956ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         ppHRegMIPS(i->Min.Cas.expd , mode64);
13966ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         vex_printf(", end\n");
13976ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj
13986ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         vex_printf("nop\n");
13996ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj
14006ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         vex_printf("%s ", sz8 ? "daddiu" : "addiu");
14016ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         ppHRegMIPS(i->Min.Cas.old , mode64);
14026ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         vex_printf(", ");
14036ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         ppHRegMIPS(i->Min.Cas.old , mode64);
14046ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         vex_printf(", 1\n");
14056ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj
14066ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         vex_printf("%s ", sz8 ? "scd" : "sc");
14076ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         ppHRegMIPS(i->Min.Cas.data , mode64);
14086ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         vex_printf(", 0(");
14096ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         ppHRegMIPS(i->Min.Cas.addr , mode64);
14106ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         vex_printf(")\n");
14116ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj
14126ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         vex_printf("movn ");
14136ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         ppHRegMIPS(i->Min.Cas.old , mode64);
14146ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         vex_printf(", ");
14156ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         ppHRegMIPS(i->Min.Cas.expd , mode64);
14166ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         vex_printf(", ");
14176ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         ppHRegMIPS(i->Min.Cas.data , mode64);
14186ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         vex_printf("\nend:");
14196ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         return;
14206ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj      }
1421362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_StoreC: {
1422362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("sc ");
1423362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.StoreC.src, mode64);
1424362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(",");
1425362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppMIPSAMode(i->Min.StoreC.dst, mode64);
1426362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1427362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
1428362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_RdWrLR: {
1429362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("%s ", i->Min.RdWrLR.wrLR ? "mtlr" : "mflr");
1430362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.RdWrLR.gpr, mode64);
1431362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1432362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
1433362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_FpUnary:
1434362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("%s ", showMIPSFpOp(i->Min.FpUnary.op));
1435362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.FpUnary.dst, mode64);
1436362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(",");
1437362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.FpUnary.src, mode64);
1438362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1439362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_FpBinary:
1440362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("%s", showMIPSFpOp(i->Min.FpBinary.op));
1441362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.FpBinary.dst, mode64);
1442362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(",");
1443362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.FpBinary.srcL, mode64);
1444362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(",");
1445362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.FpBinary.srcR, mode64);
1446362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1447b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case Min_FpTernary:
1448b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vex_printf("%s", showMIPSFpOp(i->Min.FpTernary.op));
1449b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ppHRegMIPS(i->Min.FpTernary.dst, mode64);
1450b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vex_printf(",");
1451b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ppHRegMIPS(i->Min.FpTernary.src1, mode64);
1452b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vex_printf(",");
1453b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ppHRegMIPS(i->Min.FpTernary.src2, mode64);
1454b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vex_printf(",");
1455b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ppHRegMIPS(i->Min.FpTernary.src3, mode64);
1456b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         return;
1457362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_FpConvert:
1458362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("%s", showMIPSFpOp(i->Min.FpConvert.op));
1459362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.FpConvert.dst, mode64);
1460362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(",");
1461362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.FpConvert.src, mode64);
1462362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1463362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_FpCompare:
1464362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("%s ", showMIPSFpOp(i->Min.FpCompare.op));
1465362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.FpCompare.srcL, mode64);
1466362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(",");
1467362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.FpCompare.srcR, mode64);
1468362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1469362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_FpMulAcc:
1470362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("%s ", showMIPSFpOp(i->Min.FpMulAcc.op));
1471362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.FpMulAcc.dst, mode64);
1472362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(",");
1473362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.FpMulAcc.srcML, mode64);
1474362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(",");
1475362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.FpMulAcc.srcMR, mode64);
1476362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(",");
1477362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.FpMulAcc.srcAcc, mode64);
1478362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1479362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_FpLdSt: {
1480362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         if (i->Min.FpLdSt.sz == 4) {
1481362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            if (i->Min.FpLdSt.isLoad) {
1482362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               vex_printf("lwc1 ");
1483362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               ppHRegMIPS(i->Min.FpLdSt.reg, mode64);
1484362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               vex_printf(",");
1485362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               ppMIPSAMode(i->Min.FpLdSt.addr, mode64);
1486362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            } else {
1487362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               vex_printf("swc1 ");
1488362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               ppHRegMIPS(i->Min.FpLdSt.reg, mode64);
1489362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               vex_printf(",");
1490362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               ppMIPSAMode(i->Min.FpLdSt.addr, mode64);
1491362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
1492362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         } else if (i->Min.FpLdSt.sz == 8) {
1493362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            if (i->Min.FpLdSt.isLoad) {
14941ec43e09fe3d870c3dfd3d1f4eb8198cbaf91370petarj               vex_printf("ldc1 ");
1495362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               ppHRegMIPS(i->Min.FpLdSt.reg, mode64);
1496362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               vex_printf(",");
1497362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               ppMIPSAMode(i->Min.FpLdSt.addr, mode64);
1498362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            } else {
14991ec43e09fe3d870c3dfd3d1f4eb8198cbaf91370petarj               vex_printf("sdc1 ");
1500362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               ppHRegMIPS(i->Min.FpLdSt.reg, mode64);
1501362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               vex_printf(",");
1502362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               ppMIPSAMode(i->Min.FpLdSt.addr, mode64);
1503362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
1504362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
1505362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1506362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
1507362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_MtFCSR: {
1508c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         vex_printf("ctc1 ");
1509362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.MtFCSR.src, mode64);
1510362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(", $31");
1511362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1512362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
1513362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_MfFCSR: {
1514ed39800a83baf5bffbe391f3974eb2af0f415f80Elliott Hughes         vex_printf("cfc1 ");
1515362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegMIPS(i->Min.MfFCSR.dst, mode64);
1516362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf(", $31");
1517362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1518362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
1519b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case Min_FpGpMove: {
15200e006f25d4016d7845bd016b65b5d2676a4e8c92dejanj         vex_printf("%s ", showMIPSFpGpMoveOp(i->Min.FpGpMove.op));
1521b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ppHRegMIPS(i->Min.FpGpMove.dst, mode64);
1522b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vex_printf(", ");
1523b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ppHRegMIPS(i->Min.FpGpMove.src, mode64);
1524b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         return;
1525b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      }
1526b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case Min_MoveCond: {
1527b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vex_printf("%s", showMIPSMoveCondOp(i->Min.MoveCond.op));
1528b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ppHRegMIPS(i->Min.MoveCond.dst, mode64);
1529b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vex_printf(", ");
1530b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ppHRegMIPS(i->Min.MoveCond.src, mode64);
1531b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vex_printf(", ");
1532b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         ppHRegMIPS(i->Min.MoveCond.cond, mode64);
1533b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         return;
1534b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      }
1535362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_EvCheck:
1536362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("(evCheck) lw $9, ");
1537362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppMIPSAMode(i->Min.EvCheck.amCounter, mode64);
1538362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("; addiu $9, $9, -1");
1539362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("; sw $9, ");
1540362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppMIPSAMode(i->Min.EvCheck.amCounter, mode64);
1541362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("; bgez $t9, nofail; jalr *");
1542362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppMIPSAMode(i->Min.EvCheck.amFailAddr, mode64);
1543362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vex_printf("; nofail:");
1544362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1545362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_ProfInc:
1546b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         if (mode64)
1547b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            vex_printf("(profInc) move $9, ($NotKnownYet); "
1548b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                       "ld $8, 0($9); "
1549b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                       "daddiu $8, $8, 1; "
1550b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                       "sd $8, 0($9); " );
1551b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         else
1552b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            vex_printf("(profInc) move $9, ($NotKnownYet); "
1553b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                       "lw $8, 0($9); "
1554b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                       "addiu $8, $8, 1; "
1555b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                       "sw $8, 0($9); "
1556b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                       "sltiu $1, $8, 1; "
1557b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                       "lw $8, 4($9); "
1558b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                       "addu $8, $8, $1; "
1559b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                       "sw $8, 4($9); " );
1560362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1561362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      default:
1562362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vpanic("ppMIPSInstr");
1563362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
1564362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
1565362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
1566362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1567362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* --------- Helpers for register allocation. --------- */
1568362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1569d8c64e082224b2e688abdef9219cc76fd82b373bflorianvoid getRegUsage_MIPSInstr(HRegUsage * u, const MIPSInstr * i, Bool mode64)
1570362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
1571362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   initHRegUsage(u);
1572362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   switch (i->tag) {
1573362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_LI:
1574362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, i->Min.LI.dst);
1575362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
1576362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Alu:
1577362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, i->Min.Alu.srcL);
1578362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addRegUsage_MIPSRH(u, i->Min.Alu.srcR);
1579362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, i->Min.Alu.dst);
1580362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1581362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Shft:
1582362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, i->Min.Shft.srcL);
1583362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addRegUsage_MIPSRH(u, i->Min.Shft.srcR);
1584362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, i->Min.Shft.dst);
1585362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1586362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Cmp:
1587362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, i->Min.Cmp.srcL);
1588362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, i->Min.Cmp.srcR);
1589362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, i->Min.Cmp.dst);
1590362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1591362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Unary:
1592362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, i->Min.Unary.src);
1593362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, i->Min.Unary.dst);
1594362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1595362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Mul:
1596362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, i->Min.Mul.dst);
1597362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, i->Min.Mul.srcL);
1598362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, i->Min.Mul.srcR);
1599362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1600362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Mthi:
1601362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Mtlo:
1602362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, hregMIPS_HI(mode64));
1603362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, hregMIPS_LO(mode64));
1604362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, i->Min.MtHL.src);
1605362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1606362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Mfhi:
1607362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Mflo:
1608362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, hregMIPS_HI(mode64));
1609362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, hregMIPS_LO(mode64));
1610362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, i->Min.MfHL.dst);
1611362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1612362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_MtFCSR:
1613362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, i->Min.MtFCSR.src);
1614362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1615362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_MfFCSR:
1616362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, i->Min.MfFCSR.dst);
1617362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1618362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Macc:
1619362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmModify, hregMIPS_HI(mode64));
1620362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmModify, hregMIPS_LO(mode64));
1621362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, i->Min.Macc.srcL);
1622362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, i->Min.Macc.srcR);
1623362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1624362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Div:
1625362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, hregMIPS_HI(mode64));
1626362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, hregMIPS_LO(mode64));
1627362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, i->Min.Div.srcL);
1628362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, i->Min.Div.srcR);
1629362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1630362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Call: {
1631b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         /* Logic and comments copied/modified from x86, ppc and arm back end.
1632b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            First off, claim it trashes all the caller-saved regs
1633b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            which fall within the register allocator's jurisdiction. */
1634362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         if (i->Min.Call.cond != MIPScc_AL)
1635362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            addHRegUse(u, HRmRead, i->Min.Call.src);
1636362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt argir;
1637362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, hregMIPS_GPR1(mode64));
1638362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1639362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, hregMIPS_GPR2(mode64));
1640362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, hregMIPS_GPR3(mode64));
1641362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1642362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, hregMIPS_GPR4(mode64));
1643362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, hregMIPS_GPR5(mode64));
1644362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, hregMIPS_GPR6(mode64));
1645362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, hregMIPS_GPR7(mode64));
1646362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1647362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, hregMIPS_GPR8(mode64));
1648362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, hregMIPS_GPR9(mode64));
1649362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, hregMIPS_GPR10(mode64));
1650362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, hregMIPS_GPR11(mode64));
1651362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, hregMIPS_GPR12(mode64));
1652362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, hregMIPS_GPR13(mode64));
1653362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, hregMIPS_GPR14(mode64));
1654362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, hregMIPS_GPR15(mode64));
1655362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1656362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, hregMIPS_GPR24(mode64));
1657362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, hregMIPS_GPR25(mode64));
1658b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         addHRegUse(u, HRmWrite, hregMIPS_GPR31(mode64));
1659362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1660362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* Now we have to state any parameter-carrying registers
1661b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            which might be read. This depends on the argiregs field. */
1662362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         argir = i->Min.Call.argiregs;
1663b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         if (argir & (1<<11)) addHRegUse(u, HRmRead, hregMIPS_GPR11(mode64));
1664b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         if (argir & (1<<10)) addHRegUse(u, HRmRead, hregMIPS_GPR10(mode64));
1665b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         if (argir & (1<<9)) addHRegUse(u, HRmRead, hregMIPS_GPR9(mode64));
1666b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         if (argir & (1<<8)) addHRegUse(u, HRmRead, hregMIPS_GPR8(mode64));
1667b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         if (argir & (1<<7)) addHRegUse(u, HRmRead, hregMIPS_GPR7(mode64));
1668b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         if (argir & (1<<6)) addHRegUse(u, HRmRead, hregMIPS_GPR6(mode64));
1669b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         if (argir & (1<<5)) addHRegUse(u, HRmRead, hregMIPS_GPR5(mode64));
1670b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         if (argir & (1<<4)) addHRegUse(u, HRmRead, hregMIPS_GPR4(mode64));
1671b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
1672b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         vassert(0 == (argir & ~((1 << 4) | (1 << 5) | (1 << 6)
1673b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                                 | (1 << 7) | (1 << 8) | (1 << 9) | (1 << 10)
1674b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                                 | (1 << 11))));
1675362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1676362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1677362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
1678362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      /* XDirect/XIndir/XAssisted are also a bit subtle.  They
1679362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         conditionally exit the block.  Hence we only need to list (1)
1680362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         the registers that they read, and (2) the registers that they
1681362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         write in the case where the block is not exited.  (2) is
1682362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         empty, hence only (1) is relevant here. */
1683362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_XDirect:
1684362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addRegUsage_MIPSAMode(u, i->Min.XDirect.amPC);
1685362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1686362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_XIndir:
1687362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, i->Min.XIndir.dstGA);
1688362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addRegUsage_MIPSAMode(u, i->Min.XIndir.amPC);
1689362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1690362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_XAssisted:
1691362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, i->Min.XAssisted.dstGA);
1692362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addRegUsage_MIPSAMode(u, i->Min.XAssisted.amPC);
1693362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1694362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Load:
1695362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addRegUsage_MIPSAMode(u, i->Min.Load.src);
1696362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, i->Min.Load.dst);
1697362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1698362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Store:
1699362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, i->Min.Store.src);
1700362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addRegUsage_MIPSAMode(u, i->Min.Store.dst);
1701362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1702362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_LoadL:
1703362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addRegUsage_MIPSAMode(u, i->Min.LoadL.src);
1704362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, i->Min.LoadL.dst);
1705362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
17066ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj      case Min_Cas:
17076ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         addHRegUse(u, HRmWrite, i->Min.Cas.old);
17086ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         addHRegUse(u, HRmRead, i->Min.Cas.addr);
17096ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         addHRegUse(u, HRmRead, i->Min.Cas.expd);
17106ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         addHRegUse(u, HRmModify, i->Min.Cas.data);
17116ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         return;
1712362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_StoreC:
1713362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, i->Min.StoreC.src);
1714362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, i->Min.StoreC.src);
1715362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addRegUsage_MIPSAMode(u, i->Min.StoreC.dst);
1716362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1717362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_RdWrLR:
1718362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, (i->Min.RdWrLR.wrLR ? HRmRead : HRmWrite),
1719362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                        i->Min.RdWrLR.gpr);
1720362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1721362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_FpLdSt:
1722362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         if (i->Min.FpLdSt.sz == 4) {
1723362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            addHRegUse(u, (i->Min.FpLdSt.isLoad ? HRmWrite : HRmRead),
1724362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                           i->Min.FpLdSt.reg);
1725362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            addRegUsage_MIPSAMode(u, i->Min.FpLdSt.addr);
1726362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            return;
1727362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         } else if (i->Min.FpLdSt.sz == 8) {
17281ec43e09fe3d870c3dfd3d1f4eb8198cbaf91370petarj            addHRegUse(u, (i->Min.FpLdSt.isLoad ? HRmWrite : HRmRead),
17291ec43e09fe3d870c3dfd3d1f4eb8198cbaf91370petarj                           i->Min.FpLdSt.reg);
17301ec43e09fe3d870c3dfd3d1f4eb8198cbaf91370petarj            addRegUsage_MIPSAMode(u, i->Min.FpLdSt.addr);
1731362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            return;
1732362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
1733362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
1734362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_FpUnary:
1735b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         addHRegUse(u, HRmWrite, i->Min.FpUnary.dst);
1736b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         addHRegUse(u, HRmRead, i->Min.FpUnary.src);
1737b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         return;
1738362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_FpBinary:
1739362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, i->Min.FpBinary.dst);
1740362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, i->Min.FpBinary.srcL);
1741362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, i->Min.FpBinary.srcR);
1742362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1743b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case Min_FpTernary:
1744b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         addHRegUse(u, HRmWrite, i->Min.FpTernary.dst);
1745b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         addHRegUse(u, HRmRead, i->Min.FpTernary.src1);
1746b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         addHRegUse(u, HRmRead, i->Min.FpTernary.src2);
1747b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         addHRegUse(u, HRmRead, i->Min.FpTernary.src3);
1748b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         return;
1749362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_FpConvert:
1750362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, i->Min.FpConvert.dst);
1751362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, i->Min.FpConvert.src);
1752362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1753362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_FpCompare:
1754362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmWrite, i->Min.FpCompare.dst);
1755362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, i->Min.FpCompare.srcL);
1756362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addHRegUse(u, HRmRead, i->Min.FpCompare.srcR);
1757362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1758b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case Min_FpGpMove:
1759b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         addHRegUse(u, HRmWrite, i->Min.FpGpMove.dst);
1760b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         addHRegUse(u, HRmRead, i->Min.FpGpMove.src);
1761b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         return;
1762b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case Min_MoveCond:
1763781f1bd132ec90d24ddde74d57a37f6619533517dejanj         addHRegUse(u, HRmModify, i->Min.MoveCond.dst);
1764b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         addHRegUse(u, HRmRead, i->Min.MoveCond.src);
1765b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         addHRegUse(u, HRmRead, i->Min.MoveCond.cond);
1766362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1767362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_EvCheck:
1768362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* We expect both amodes only to mention %ebp, so this is in
1769362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            fact pointless, since %ebp isn't allocatable, but anyway.. */
1770362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addRegUsage_MIPSAMode(u, i->Min.EvCheck.amCounter);
1771362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         addRegUsage_MIPSAMode(u, i->Min.EvCheck.amFailAddr);
1772362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1773362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_ProfInc:
1774362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* does not use any registers. */
1775362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1776362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      default:
1777362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppMIPSInstr(i, mode64);
1778362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vpanic("getRegUsage_MIPSInstr");
1779362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
1780362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
1781362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
1782362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1783362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* local helper */
1784362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjstatic void mapReg(HRegRemap * m, HReg * r)
1785362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
1786362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   *r = lookupHRegRemap(m, *r);
1787362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
1788362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1789362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjvoid mapRegs_MIPSInstr(HRegRemap * m, MIPSInstr * i, Bool mode64)
1790362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
1791362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   switch (i->tag) {
1792362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_LI:
1793362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.LI.dst);
1794362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
1795362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Alu:
1796362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.Alu.srcL);
1797362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapRegs_MIPSRH(m, i->Min.Alu.srcR);
1798362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.Alu.dst);
1799362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1800362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Shft:
1801362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.Shft.srcL);
1802362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapRegs_MIPSRH(m, i->Min.Shft.srcR);
1803362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.Shft.dst);
1804362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1805362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Cmp:
1806362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.Cmp.srcL);
1807362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.Cmp.srcR);
1808362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.Cmp.dst);
1809362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1810362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Unary:
1811362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.Unary.src);
1812362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.Unary.dst);
1813362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1814362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Mul:
1815362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.Mul.dst);
1816362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.Mul.srcL);
1817362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.Mul.srcR);
1818362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1819362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Mthi:
1820362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Mtlo:
1821362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.MtHL.src);
1822362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1823362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Mfhi:
1824362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Mflo:
1825362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.MfHL.dst);
1826362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1827362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Macc:
1828362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.Macc.srcL);
1829362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.Macc.srcR);
1830362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1831362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Div:
1832362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.Div.srcL);
1833362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.Div.srcR);
1834362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1835362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Call:
1836362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         {
1837362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            if (i->Min.Call.cond != MIPScc_AL)
1838362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               mapReg(m, &i->Min.Call.src);
1839362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            return;
1840362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
1841362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_XDirect:
1842362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapRegs_MIPSAMode(m, i->Min.XDirect.amPC);
1843362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1844362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_XIndir:
1845362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.XIndir.dstGA);
1846362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapRegs_MIPSAMode(m, i->Min.XIndir.amPC);
1847362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1848362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_XAssisted:
1849362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.XAssisted.dstGA);
1850362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapRegs_MIPSAMode(m, i->Min.XAssisted.amPC);
1851362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1852362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Load:
1853362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapRegs_MIPSAMode(m, i->Min.Load.src);
1854362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.Load.dst);
1855362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1856362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Store:
1857362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.Store.src);
1858362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapRegs_MIPSAMode(m, i->Min.Store.dst);
1859362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1860362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_LoadL:
1861362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapRegs_MIPSAMode(m, i->Min.LoadL.src);
1862362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.LoadL.dst);
1863362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
18646ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj      case Min_Cas:
18656ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         mapReg(m, &i->Min.Cas.old);
18666ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         mapReg(m, &i->Min.Cas.addr);
18676ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         mapReg(m, &i->Min.Cas.expd);
18686ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         mapReg(m, &i->Min.Cas.data);
18696ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         return;
1870362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_StoreC:
1871362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.StoreC.src);
1872362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapRegs_MIPSAMode(m, i->Min.StoreC.dst);
1873362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1874362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_RdWrLR:
1875362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.RdWrLR.gpr);
1876362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1877362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_FpLdSt:
1878362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         if (i->Min.FpLdSt.sz == 4) {
1879362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            mapReg(m, &i->Min.FpLdSt.reg);
1880362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            mapRegs_MIPSAMode(m, i->Min.FpLdSt.addr);
1881362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            return;
1882362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         } else if (i->Min.FpLdSt.sz == 8) {
18831ec43e09fe3d870c3dfd3d1f4eb8198cbaf91370petarj            mapReg(m, &i->Min.FpLdSt.reg);
18841ec43e09fe3d870c3dfd3d1f4eb8198cbaf91370petarj            mapRegs_MIPSAMode(m, i->Min.FpLdSt.addr);
1885362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            return;
1886362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
1887362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
1888362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_FpUnary:
1889b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         mapReg(m, &i->Min.FpUnary.dst);
1890b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         mapReg(m, &i->Min.FpUnary.src);
1891b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         return;
1892362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_FpBinary:
1893362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.FpBinary.dst);
1894362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.FpBinary.srcL);
1895362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.FpBinary.srcR);
1896362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1897b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case Min_FpTernary:
1898b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         mapReg(m, &i->Min.FpTernary.dst);
1899b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         mapReg(m, &i->Min.FpTernary.src1);
1900b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         mapReg(m, &i->Min.FpTernary.src2);
1901b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         mapReg(m, &i->Min.FpTernary.src3);
1902b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         return;
1903362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_FpConvert:
1904362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.FpConvert.dst);
1905362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.FpConvert.src);
1906362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1907362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_FpCompare:
1908362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.FpCompare.dst);
1909362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.FpCompare.srcL);
1910362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.FpCompare.srcR);
1911362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1912362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_MtFCSR:
1913362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.MtFCSR.src);
1914362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1915362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_MfFCSR:
1916362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapReg(m, &i->Min.MfFCSR.dst);
1917362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1918b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case Min_FpGpMove:
1919b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         mapReg(m, &i->Min.FpGpMove.dst);
1920b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         mapReg(m, &i->Min.FpGpMove.src);
1921b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         return;
1922b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case Min_MoveCond:
1923b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         mapReg(m, &i->Min.MoveCond.dst);
1924b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         mapReg(m, &i->Min.MoveCond.src);
1925b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         mapReg(m, &i->Min.MoveCond.cond);
1926362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1927362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_EvCheck:
1928362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* We expect both amodes only to mention %ebp, so this is in
1929362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            fact pointless, since %ebp isn't allocatable, but anyway.. */
1930362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapRegs_MIPSAMode(m, i->Min.EvCheck.amCounter);
1931362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         mapRegs_MIPSAMode(m, i->Min.EvCheck.amFailAddr);
1932362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1933362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_ProfInc:
1934362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* does not use any registers. */
1935362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return;
1936362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      default:
1937362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppMIPSInstr(i, mode64);
1938362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vpanic("mapRegs_MIPSInstr");
1939362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
1940362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
1941362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1942362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
1943362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1944362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* Figure out if i represents a reg-reg move, and if so assign the
1945362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   source and destination to *src and *dst.  If in doubt say No.  Used
1946c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj   by the register allocator to do move coalescing.
1947362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj*/
1948d8c64e082224b2e688abdef9219cc76fd82b373bflorianBool isMove_MIPSInstr(const MIPSInstr * i, HReg * src, HReg * dst)
1949362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
1950362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   /* Moves between integer regs */
1951362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   if (i->tag == Min_Alu) {
1952b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      /* or Rd,Rs,Rs == mr Rd,Rs */
1953362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      if (i->Min.Alu.op != Malu_OR)
1954362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return False;
1955362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      if (i->Min.Alu.srcR->tag != Mrh_Reg)
1956362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return False;
1957a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj      if (!sameHReg(i->Min.Alu.srcR->Mrh.Reg.reg, i->Min.Alu.srcL))
1958362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         return False;
1959362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      *src = i->Min.Alu.srcL;
1960362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      *dst = i->Min.Alu.dst;
1961362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      return True;
1962362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
1963362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return False;
1964362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
1965362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1966362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* Generate mips spill/reload instructions under the direction of the
1967b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   register allocator. */
1968362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjvoid genSpill_MIPS( /*OUT*/ HInstr ** i1, /*OUT*/ HInstr ** i2, HReg rreg,
1969362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                    Int offsetB, Bool mode64)
1970362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
1971362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   MIPSAMode *am;
1972362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(offsetB >= 0);
1973362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(!hregIsVirtual(rreg));
1974362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   *i1 = *i2 = NULL;
1975362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   am = MIPSAMode_IR(offsetB, GuestStatePointer(mode64));
1976362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
1977362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   switch (hregClass(rreg)) {
1978362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case HRcInt64:
1979362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vassert(mode64);
1980362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         *i1 = MIPSInstr_Store(8, am, rreg, mode64);
1981362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
1982362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case HRcInt32:
1983362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vassert(!mode64);
1984362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         *i1 = MIPSInstr_Store(4, am, rreg, mode64);
1985362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
1986362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case HRcFlt32:
1987362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vassert(!mode64);
1988362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         *i1 = MIPSInstr_FpLdSt(False /*Store */ , 4, rreg, am);
1989362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
1990362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case HRcFlt64:
1991362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         *i1 = MIPSInstr_FpLdSt(False /*Store */ , 8, rreg, am);
1992362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
1993362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      default:
1994362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegClass(hregClass(rreg));
1995362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vpanic("genSpill_MIPS: unimplemented regclass");
1996362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
1997362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
1998362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
1999362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2000362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjvoid genReload_MIPS( /*OUT*/ HInstr ** i1, /*OUT*/ HInstr ** i2, HReg rreg,
2001362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     Int offsetB, Bool mode64)
2002362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
2003362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   MIPSAMode *am;
2004362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(!hregIsVirtual(rreg));
2005362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   am = MIPSAMode_IR(offsetB, GuestStatePointer(mode64));
2006362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2007362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   switch (hregClass(rreg)) {
2008362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case HRcInt64:
2009362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vassert(mode64);
2010362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         *i1 = MIPSInstr_Load(8, rreg, am, mode64);
2011362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
2012362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case HRcInt32:
2013362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vassert(!mode64);
2014362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         *i1 = MIPSInstr_Load(4, rreg, am, mode64);
2015362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
2016362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case HRcFlt32:
2017362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         if (mode64)
2018362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            *i1 = MIPSInstr_FpLdSt(True /*Load */ , 8, rreg, am);
2019362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         else
2020362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            *i1 = MIPSInstr_FpLdSt(True /*Load */ , 4, rreg, am);
2021362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
2022362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case HRcFlt64:
2023362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         *i1 = MIPSInstr_FpLdSt(True /*Load */ , 8, rreg, am);
2024362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
2025362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      default:
2026362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ppHRegClass(hregClass(rreg));
2027362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vpanic("genReload_MIPS: unimplemented regclass");
2028362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
2029362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
2030362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
2031362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2032362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* --------- The mips assembler --------- */
2033362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2034a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjinline static UInt iregNo(HReg r, Bool mode64)
2035362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
2036362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   UInt n;
20374b5abc2844e62bd06a9e7dcbfae6ea3ff04fb69apetarj   vassert(hregClass(r) == (mode64 ? HRcInt64 : HRcInt32));
2038362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(!hregIsVirtual(r));
2039a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   n = hregEncoding(r);
2040362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(n <= 32);
2041362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return n;
2042362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
2043362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2044a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjinline static UInt fregNo(HReg r, Bool mode64)
2045362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
2046362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   UInt n;
2047362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(!hregIsVirtual(r));
2048a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   n = hregEncoding(r);
2049362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(n <= 31);
2050362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return n;
2051362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
2052362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2053a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardjinline static UInt dregNo(HReg r)
2054362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
2055362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   UInt n;
2056362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(!hregIsVirtual(r));
2057a5b502299bfc9d97f4c2c9f61cdc1a0a65e1da61sewardj   n = hregEncoding(r);
2058362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(n <= 31);
2059362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return n;
2060362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
2061362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2062362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* Emit 32bit instruction */
2063362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjstatic UChar *emit32(UChar * p, UInt w32)
2064362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
2065362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj#if defined (_MIPSEL)
2066362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   *p++ = toUChar(w32 & 0x000000FF);
2067362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   *p++ = toUChar((w32 >> 8) & 0x000000FF);
2068362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   *p++ = toUChar((w32 >> 16) & 0x000000FF);
2069362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   *p++ = toUChar((w32 >> 24) & 0x000000FF);
20707e5aa0dfae264df1588d5d70dcc7e7c591daaa29philippe/* HACK !!!!
20717e5aa0dfae264df1588d5d70dcc7e7c591daaa29philippe   MIPS endianess is decided at compile time using gcc defined
20727e5aa0dfae264df1588d5d70dcc7e7c591daaa29philippe   symbols _MIPSEL or _MIPSEB. When compiling libvex in a cross-arch
20737e5aa0dfae264df1588d5d70dcc7e7c591daaa29philippe   setup, then none of these is defined. We just choose here by default
20747e5aa0dfae264df1588d5d70dcc7e7c591daaa29philippe   mips Big Endian to allow libvexmultiarch_test to work when using
20757e5aa0dfae264df1588d5d70dcc7e7c591daaa29philippe   a mips host architecture.
20767e5aa0dfae264df1588d5d70dcc7e7c591daaa29philippe   A cleaner way would be to either have mips using 'dynamic endness'
20777e5aa0dfae264df1588d5d70dcc7e7c591daaa29philippe   (like ppc64be or le, decided at runtime) or at least defining
20787e5aa0dfae264df1588d5d70dcc7e7c591daaa29philippe   by default _MIPSEB when compiling on a non mips system.
20797e5aa0dfae264df1588d5d70dcc7e7c591daaa29philippe#elif defined (_MIPSEB).
20807e5aa0dfae264df1588d5d70dcc7e7c591daaa29philippe*/
20817e5aa0dfae264df1588d5d70dcc7e7c591daaa29philippe#else
2082362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   *p++ = toUChar((w32 >> 24) & 0x000000FF);
2083362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   *p++ = toUChar((w32 >> 16) & 0x000000FF);
2084362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   *p++ = toUChar((w32 >> 8) & 0x000000FF);
2085362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   *p++ = toUChar(w32 & 0x000000FF);
2086362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj#endif
2087362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return p;
2088362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
2089362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* Fetch an instruction */
2090362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjstatic UInt fetch32 ( UChar* p )
2091362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
2092362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   UInt w32 = 0;
2093362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj#if defined (_MIPSEL)
2094362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   w32 |= ((0xFF & (UInt)p[0]) << 0);
2095362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   w32 |= ((0xFF & (UInt)p[1]) << 8);
2096362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   w32 |= ((0xFF & (UInt)p[2]) << 16);
2097362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   w32 |= ((0xFF & (UInt)p[3]) << 24);
2098362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj#elif defined (_MIPSEB)
2099362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   w32 |= ((0xFF & (UInt)p[0]) << 24);
2100362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   w32 |= ((0xFF & (UInt)p[1]) << 16);
2101362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   w32 |= ((0xFF & (UInt)p[2]) <<  8);
2102362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   w32 |= ((0xFF & (UInt)p[3]) <<  0);
2103362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj#endif
2104362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return w32;
2105362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
2106362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2107362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* physical structure of mips instructions */
2108c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj/* type I : opcode    - 6 bits
2109362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         rs         - 5 bits
2110362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         rt         - 5 bits
2111362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         immediate - 16 bits
2112362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj*/
2113362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjstatic UChar *mkFormI(UChar * p, UInt opc, UInt rs, UInt rt, UInt imm)
2114362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
2115362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   UInt theInstr;
2116362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(opc < 0x40);
2117362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(rs < 0x20);
2118362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(rt < 0x20);
2119362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   imm = imm & 0xFFFF;
2120362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   theInstr = ((opc << 26) | (rs << 21) | (rt << 16) | (imm));
2121362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return emit32(p, theInstr);
2122362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
2123362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2124362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* type R: opcode    - 6 bits
2125362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         rs    - 5 bits
2126362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         rt    - 5 bits
2127362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         rd    - 5 bits
2128362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         sa    - 5 bits
2129362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         func  - 6 bits
2130362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj*/
2131362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjstatic UChar *mkFormR(UChar * p, UInt opc, UInt rs, UInt rt, UInt rd, UInt sa,
2132362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            UInt func)
2133362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
2134362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   if (rs >= 0x20)
2135b173774421d015736c2316b5e6e998e7de545a5cflorian      vex_printf("rs = %u\n", rs);
2136362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   UInt theInstr;
2137362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(opc < 0x40);
2138362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(rs < 0x20);
2139362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(rt < 0x20);
2140362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(rd < 0x20);
2141362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(sa < 0x20);
2142362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   func = func & 0xFFFF;
2143362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   theInstr = ((opc << 26) | (rs << 21) | (rt << 16) | (rd << 11) | (sa << 6) |
2144362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               (func));
2145362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2146362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return emit32(p, theInstr);
2147362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
2148362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2149362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjstatic UChar *mkFormS(UChar * p, UInt opc1, UInt rRD, UInt rRS, UInt rRT,
2150362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                      UInt sa, UInt opc2)
2151362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
2152362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   UInt theInstr;
2153362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(opc1 <= 0x3F);
2154362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(rRD < 0x20);
2155362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(rRS < 0x20);
2156362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(rRT < 0x20);
2157362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(opc2 <= 0x3F);
2158362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(sa >= 0 && sa <= 0x3F);
2159362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2160362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   theInstr = ((opc1 << 26) | (rRS << 21) | (rRT << 16) | (rRD << 11) |
2161362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj              ((sa & 0x1F) << 6) | (opc2));
2162362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2163362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return emit32(p, theInstr);
2164362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
2165362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2166362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjstatic UChar *doAMode_IR(UChar * p, UInt opc1, UInt rSD, MIPSAMode * am,
2167362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                         Bool mode64)
2168362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
2169362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   UInt rA, idx, r_dst;
2170362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(am->tag == Mam_IR);
2171362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(am->Mam.IR.index < 0x10000);
2172362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2173362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   rA = iregNo(am->Mam.IR.base, mode64);
2174362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   idx = am->Mam.IR.index;
2175362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2176362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   if (rSD == 33 || rSD == 34)
2177362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      r_dst = 24;
2178362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   else
2179362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      r_dst = rSD;
2180362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2181362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   if (opc1 < 40) {
2182b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      /* load */
2183362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      if (rSD == 33)
2184362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* mfhi */
2185362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         p = mkFormR(p, 0, 0, 0, r_dst, 0, 16);
2186362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      else if (rSD == 34)
2187362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* mflo */
2188362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         p = mkFormR(p, 0, 0, 0, r_dst, 0, 18);
2189362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
2190362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2191362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   p = mkFormI(p, opc1, rA, r_dst, idx);
2192362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2193362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   if (opc1 >= 40) {
2194b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      /* store */
2195362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      if (rSD == 33)
2196362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* mthi */
2197362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         p = mkFormR(p, 0, r_dst, 0, 0, 0, 17);
2198362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      else if (rSD == 34)
2199362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* mtlo */
2200362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         p = mkFormR(p, 0, r_dst, 0, 0, 0, 19);
2201362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
2202362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2203362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return p;
2204362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
2205362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2206362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjstatic UChar *doAMode_RR(UChar * p, UInt opc1, UInt rSD, MIPSAMode * am,
2207362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                         Bool mode64)
2208362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
2209362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   UInt rA, rB, r_dst;
2210362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(am->tag == Mam_RR);
2211362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2212362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   rA = iregNo(am->Mam.RR.base, mode64);
2213362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   rB = iregNo(am->Mam.RR.index, mode64);
2214362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2215362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   if (rSD == 33 || rSD == 34)
2216362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      r_dst = 24;
2217362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   else
2218362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      r_dst = rSD;
2219362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2220362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   if (opc1 < 40) {
2221b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      /* load */
2222362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      if (rSD == 33)
2223362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* mfhi */
2224362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         p = mkFormR(p, 0, 0, 0, r_dst, 0, 16);
2225362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      else if (rSD == 34)
2226362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* mflo */
2227362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         p = mkFormR(p, 0, 0, 0, r_dst, 0, 18);
2228362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
2229b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
2230362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   if (mode64) {
2231a759d17f9b139ce17e9185291867fdeae3ad23efdejanj      /* daddu rA, rA, rB$
2232a759d17f9b139ce17e9185291867fdeae3ad23efdejanj         sd/ld r_dst, 0(rA)$
2233a759d17f9b139ce17e9185291867fdeae3ad23efdejanj         dsubu rA, rA, rB */
2234362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      p = mkFormR(p, 0, rA, rB, rA, 0, 45);
2235362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      p = mkFormI(p, opc1, rA, r_dst, 0);
2236a759d17f9b139ce17e9185291867fdeae3ad23efdejanj      p = mkFormR(p, 0, rA, rB, rA, 0, 47);
2237362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   } else {
2238a759d17f9b139ce17e9185291867fdeae3ad23efdejanj      /* addu rA, rA, rB
2239a759d17f9b139ce17e9185291867fdeae3ad23efdejanj         sw/lw r_dst, 0(rA)
2240a759d17f9b139ce17e9185291867fdeae3ad23efdejanj         subu rA, rA, rB */
2241362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      p = mkFormR(p, 0, rA, rB, rA, 0, 33);
2242362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      p = mkFormI(p, opc1, rA, r_dst, 0);
2243a759d17f9b139ce17e9185291867fdeae3ad23efdejanj      p = mkFormR(p, 0, rA, rB, rA, 0, 35);
2244362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
2245362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   if (opc1 >= 40) {
2246b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      /* store */
2247362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      if (rSD == 33)
2248362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* mthi */
2249362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         p = mkFormR(p, 0, r_dst, 0, 0, 0, 17);
2250362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      else if (rSD == 34)
2251362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* mtlo */
2252362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         p = mkFormR(p, 0, r_dst, 0, 0, 0, 19);
2253362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
2254362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2255362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return p;
2256362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
2257362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2258362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* Load imm to r_dst */
2259362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjstatic UChar *mkLoadImm(UChar * p, UInt r_dst, ULong imm, Bool mode64)
2260362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
2261362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   if (!mode64) {
2262362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      vassert(r_dst < 0x20);
2263362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      UInt u32 = (UInt) imm;
2264362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      Int s32 = (Int) u32;
2265362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      Long s64 = (Long) s32;
2266362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      imm = (ULong) s64;
2267362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
2268362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2269362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   if (imm >= 0xFFFFFFFFFFFF8000ULL || imm < 0x8000) {
2270b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      /* sign-extendable from 16 bits
2271b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         addiu r_dst, 0, imm  => li r_dst, imm */
2272362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      p = mkFormI(p, 9, 0, r_dst, imm & 0xFFFF);
2273362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   } else {
2274362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      if (imm >= 0xFFFFFFFF80000000ULL || imm < 0x80000000ULL) {
2275b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         /* sign-extendable from 32 bits
2276b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            addiu r_dst, r0, (imm >> 16) => lis r_dst, (imm >> 16)
2277b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            lui r_dst, (imm >> 16) */
2278362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         p = mkFormI(p, 15, 0, r_dst, (imm >> 16) & 0xFFFF);
2279b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         /* ori r_dst, r_dst, (imm & 0xFFFF) */
2280362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         p = mkFormI(p, 13, r_dst, r_dst, imm & 0xFFFF);
2281362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      } else {
2282362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vassert(mode64);
2283b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         /* lui load in upper half of low word */
2284362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         p = mkFormI(p, 15, 0, r_dst, (imm >> 48) & 0xFFFF);
2285b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         /* ori */
2286362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         p = mkFormI(p, 13, r_dst, r_dst, (imm >> 32) & 0xFFFF);
2287b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         /* shift */
2288362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         p = mkFormS(p, 0, r_dst, 0, r_dst, 16, 56);
2289b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         /* ori */
2290362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         p = mkFormI(p, 13, r_dst, r_dst, (imm >> 16) & 0xFFFF);
2291b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         /* shift */
2292362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         p = mkFormS(p, 0, r_dst, 0, r_dst, 16, 56);
2293b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         /* ori */
2294362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         p = mkFormI(p, 13, r_dst, r_dst, imm & 0xFFFF);
2295362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
2296362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
2297362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return p;
2298362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
2299362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2300b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj/* A simplified version of mkLoadImm that always generates 2 or 6
2301362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   instructions (32 or 64 bits respectively) even if it could generate
2302362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   fewer.  This is needed for generating fixed sized patchable
2303362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   sequences. */
2304b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarjstatic UChar* mkLoadImm_EXACTLY2or6 ( UChar* p,
2305b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                                      UInt r_dst, ULong imm, Bool mode64)
2306362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
2307362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(r_dst < 0x20);
2308362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2309362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   if (!mode64) {
2310362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      /* In 32-bit mode, make sure the top 32 bits of imm are a sign
2311b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         extension of the bottom 32 bits. (Probably unnecessary.) */
2312362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      UInt u32 = (UInt)imm;
2313362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      Int  s32 = (Int)u32;
2314362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      Long s64 = (Long)s32;
2315362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      imm = (ULong)s64;
2316362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
2317362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2318362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   if (!mode64) {
2319b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      /* sign-extendable from 32 bits
2320b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         addiu r_dst, r0, (imm >> 16) => lis r_dst, (imm >> 16)
2321b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         lui r_dst, (imm >> 16) */
2322362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      p = mkFormI(p, 15, 0, r_dst, (imm >> 16) & 0xFFFF);
2323b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      /* ori r_dst, r_dst, (imm & 0xFFFF) */
2324362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      p = mkFormI(p, 13, r_dst, r_dst, imm & 0xFFFF);
2325362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   } else {
2326b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      /* full 64bit immediate load: 6 (six!) insns. */
2327b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      vassert(mode64);
2328b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      /* lui load in upper half of low word */
2329b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      p = mkFormI(p, 15, 0, r_dst, (imm >> 48) & 0xFFFF);
2330b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      /* ori */
2331b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      p = mkFormI(p, 13, r_dst, r_dst, (imm >> 32) & 0xFFFF);
2332b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      /* shift */
2333b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      p = mkFormS(p, 0, r_dst, 0, r_dst, 16, 56);
2334b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      /* ori */
2335b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      p = mkFormI(p, 13, r_dst, r_dst, (imm >> 16) & 0xFFFF);
2336b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      /* shift */
2337b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      p = mkFormS(p, 0, r_dst, 0, r_dst, 16, 56);
2338b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      /* ori */
2339b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      p = mkFormI(p, 13, r_dst, r_dst, imm & 0xFFFF);
2340362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
2341362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return p;
2342362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
2343362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2344362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* Checks whether the sequence of bytes at p was indeed created
2345b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   by mkLoadImm_EXACTLY2or6 with the given parameters. */
2346b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarjstatic Bool isLoadImm_EXACTLY2or6 ( UChar* p_to_check,
2347362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                                    UInt r_dst, ULong imm, Bool mode64 )
2348362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
2349362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(r_dst < 0x20);
2350362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   Bool ret;
2351362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   if (!mode64) {
2352362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      /* In 32-bit mode, make sure the top 32 bits of imm are a sign
2353362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         extension of the bottom 32 bits.  (Probably unnecessary.) */
2354362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      UInt u32 = (UInt)imm;
2355362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      Int  s32 = (Int)u32;
2356362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      Long s64 = (Long)s32;
2357362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      imm = (ULong)s64;
2358362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
2359362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2360362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   if (!mode64) {
2361362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      UInt   expect[2] = { 0, 0 };
2362362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      UChar* p         = (UChar*)&expect[0];
2363b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      /* lui r_dst, (immi >> 16) */
2364362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      p = mkFormI(p, 15, 0, r_dst, (imm >> 16) & 0xFFFF);
2365b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      /* ori r_dst, r_dst, (imm & 0xFFFF) */
2366362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      p = mkFormI(p, 13, r_dst, r_dst, imm & 0xFFFF);
2367362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      vassert(p == (UChar*)&expect[2]);
2368362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2369362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      ret = fetch32(p_to_check + 0) == expect[0]
2370b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            && fetch32(p_to_check + 4) == expect[1];
2371362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   } else {
2372b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      UInt   expect[6] = { 0, 0, 0, 0, 0, 0};
2373b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      UChar* p         = (UChar*)&expect[0];
2374b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      /* lui load in upper half of low word */
2375b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      p = mkFormI(p, 15, 0, r_dst, (imm >> 48) & 0xFFFF);
2376b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      /* ori */
2377b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      p = mkFormI(p, 13, r_dst, r_dst, (imm >> 32) & 0xFFFF);
2378b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      /* shift */
2379b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      p = mkFormS(p, 0, r_dst, 0, r_dst, 16, 56);
2380b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      /* ori */
2381b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      p = mkFormI(p, 13, r_dst, r_dst, (imm >> 16) & 0xFFFF);
2382b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      /* shift */
2383b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      p = mkFormS(p, 0, r_dst, 0, r_dst, 16, 56);
2384b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      /* ori */
2385b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      p = mkFormI(p, 13, r_dst, r_dst, imm & 0xFFFF);
2386b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      vassert(p == (UChar*)&expect[6]);
2387b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
2388b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      ret = fetch32(p_to_check + 0) == expect[0]
2389b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            && fetch32(p_to_check + 4) == expect[1]
2390b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            && fetch32(p_to_check + 8) == expect[2]
2391b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            && fetch32(p_to_check + 12) == expect[3]
2392b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            && fetch32(p_to_check + 16) == expect[4]
2393b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            && fetch32(p_to_check + 20) == expect[5];
2394362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
2395362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return ret;
2396362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
2397362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
23980c30de83fbcb0f485c34c60f64e2994eaff37875petarj/* Generate a machine-word sized load or store. Simplified version of
23990c30de83fbcb0f485c34c60f64e2994eaff37875petarj   the Min_Load and Min_Store cases below.
24000c30de83fbcb0f485c34c60f64e2994eaff37875petarj   This will generate 32-bit load/store on MIPS32, and 64-bit load/store on
24010c30de83fbcb0f485c34c60f64e2994eaff37875petarj   MIPS64 platforms.
24020c30de83fbcb0f485c34c60f64e2994eaff37875petarj*/
24030c30de83fbcb0f485c34c60f64e2994eaff37875petarjstatic UChar* do_load_or_store_machine_word ( UChar* p, Bool isLoad, UInt reg,
24040c30de83fbcb0f485c34c60f64e2994eaff37875petarj                                              MIPSAMode* am, Bool mode64 )
2405362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
2406362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   if (isLoad) { /* load */
2407362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      switch (am->tag) {
2408362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         case Mam_IR:
2409362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            if (mode64) {
2410362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               vassert(0 == (am->Mam.IR.index & 3));
2411362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
24124b5abc2844e62bd06a9e7dcbfae6ea3ff04fb69apetarj            p = doAMode_IR(p, mode64 ? 55 : 35, reg, am, mode64);
2413362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            break;
2414362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         case Mam_RR:
2415362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            /* we could handle this case, but we don't expect to ever
2416362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               need to. */
2417362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            vassert(0);
2418362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            break;
2419362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         default:
2420362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            vassert(0);
2421362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            break;
2422362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
2423362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   } else /* store */ {
2424362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      switch (am->tag) {
2425362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         case Mam_IR:
2426362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            if (mode64) {
2427362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               vassert(0 == (am->Mam.IR.index & 3));
2428362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
24294b5abc2844e62bd06a9e7dcbfae6ea3ff04fb69apetarj            p = doAMode_IR(p, mode64 ? 63 : 43, reg, am, mode64);
2430362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            break;
2431362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         case Mam_RR:
2432362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            /* we could handle this case, but we don't expect to ever
2433362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               need to. */
2434362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            vassert(0);
2435362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            break;
2436362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         default:
2437362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            vassert(0);
2438362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            break;
2439362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
2440362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
2441362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return p;
2442362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
2443362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
24440c30de83fbcb0f485c34c60f64e2994eaff37875petarj/* Generate a 32-bit sized load or store. Simplified version of
24450c30de83fbcb0f485c34c60f64e2994eaff37875petarj   do_load_or_store_machine_word above. */
24460c30de83fbcb0f485c34c60f64e2994eaff37875petarjstatic UChar* do_load_or_store_word32 ( UChar* p, Bool isLoad, UInt reg,
24470c30de83fbcb0f485c34c60f64e2994eaff37875petarj                                        MIPSAMode* am, Bool mode64 )
24480c30de83fbcb0f485c34c60f64e2994eaff37875petarj{
24490c30de83fbcb0f485c34c60f64e2994eaff37875petarj   if (isLoad) { /* load */
24500c30de83fbcb0f485c34c60f64e2994eaff37875petarj      switch (am->tag) {
24510c30de83fbcb0f485c34c60f64e2994eaff37875petarj         case Mam_IR:
24520c30de83fbcb0f485c34c60f64e2994eaff37875petarj            if (mode64) {
24530c30de83fbcb0f485c34c60f64e2994eaff37875petarj               vassert(0 == (am->Mam.IR.index & 3));
24540c30de83fbcb0f485c34c60f64e2994eaff37875petarj            }
24550c30de83fbcb0f485c34c60f64e2994eaff37875petarj            p = doAMode_IR(p, 35, reg, am, mode64);
24560c30de83fbcb0f485c34c60f64e2994eaff37875petarj            break;
24570c30de83fbcb0f485c34c60f64e2994eaff37875petarj         case Mam_RR:
24580c30de83fbcb0f485c34c60f64e2994eaff37875petarj            /* we could handle this case, but we don't expect to ever
24590c30de83fbcb0f485c34c60f64e2994eaff37875petarj               need to. */
24600c30de83fbcb0f485c34c60f64e2994eaff37875petarj            vassert(0);
24610c30de83fbcb0f485c34c60f64e2994eaff37875petarj            break;
24620c30de83fbcb0f485c34c60f64e2994eaff37875petarj         default:
24630c30de83fbcb0f485c34c60f64e2994eaff37875petarj            vassert(0);
24640c30de83fbcb0f485c34c60f64e2994eaff37875petarj            break;
24650c30de83fbcb0f485c34c60f64e2994eaff37875petarj      }
24660c30de83fbcb0f485c34c60f64e2994eaff37875petarj   } else /* store */ {
24670c30de83fbcb0f485c34c60f64e2994eaff37875petarj      switch (am->tag) {
24680c30de83fbcb0f485c34c60f64e2994eaff37875petarj         case Mam_IR:
24690c30de83fbcb0f485c34c60f64e2994eaff37875petarj            if (mode64) {
24700c30de83fbcb0f485c34c60f64e2994eaff37875petarj               vassert(0 == (am->Mam.IR.index & 3));
24710c30de83fbcb0f485c34c60f64e2994eaff37875petarj            }
24720c30de83fbcb0f485c34c60f64e2994eaff37875petarj            p = doAMode_IR(p, 43, reg, am, mode64);
24730c30de83fbcb0f485c34c60f64e2994eaff37875petarj            break;
24740c30de83fbcb0f485c34c60f64e2994eaff37875petarj         case Mam_RR:
24750c30de83fbcb0f485c34c60f64e2994eaff37875petarj            /* we could handle this case, but we don't expect to ever
24760c30de83fbcb0f485c34c60f64e2994eaff37875petarj               need to. */
24770c30de83fbcb0f485c34c60f64e2994eaff37875petarj            vassert(0);
24780c30de83fbcb0f485c34c60f64e2994eaff37875petarj            break;
24790c30de83fbcb0f485c34c60f64e2994eaff37875petarj         default:
24800c30de83fbcb0f485c34c60f64e2994eaff37875petarj            vassert(0);
24810c30de83fbcb0f485c34c60f64e2994eaff37875petarj            break;
24820c30de83fbcb0f485c34c60f64e2994eaff37875petarj      }
24830c30de83fbcb0f485c34c60f64e2994eaff37875petarj   }
24840c30de83fbcb0f485c34c60f64e2994eaff37875petarj   return p;
24850c30de83fbcb0f485c34c60f64e2994eaff37875petarj}
24860c30de83fbcb0f485c34c60f64e2994eaff37875petarj
2487362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* Move r_dst to r_src */
2488362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjstatic UChar *mkMoveReg(UChar * p, UInt r_dst, UInt r_src)
2489362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
2490362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(r_dst < 0x20);
2491362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(r_src < 0x20);
2492362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2493362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   if (r_dst != r_src) {
2494362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      /* or r_dst, r_src, r_src */
2495362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      p = mkFormR(p, 0, r_src, r_src, r_dst, 0, 37);
2496362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
2497362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return p;
2498362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
2499362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2500362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* Emit an instruction into buf and return the number of bytes used.
2501362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   Note that buf is not the insn's final place, and therefore it is
2502362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   imperative to emit position-independent code.  If the emitted
2503362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   instruction was a profiler inc, set *is_profInc to True, else
2504362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   leave it unchanged. */
2505362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardjInt emit_MIPSInstr ( /*MB_MOD*/Bool* is_profInc,
2506d8c64e082224b2e688abdef9219cc76fd82b373bflorian                     UChar* buf, Int nbuf, const MIPSInstr* i,
2507362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     Bool mode64,
25089b76916dcc1628e133d57db001563429c6e3a590sewardj                     VexEndness endness_host,
25098462d113e3efeacceb304222dada8d85f748295aflorian                     const void* disp_cp_chain_me_to_slowEP,
25108462d113e3efeacceb304222dada8d85f748295aflorian                     const void* disp_cp_chain_me_to_fastEP,
25118462d113e3efeacceb304222dada8d85f748295aflorian                     const void* disp_cp_xindir,
25128462d113e3efeacceb304222dada8d85f748295aflorian                     const void* disp_cp_xassisted )
2513362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
2514362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   UChar *p = &buf[0];
2515362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   UChar *ptmp = p;
2516362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(nbuf >= 32);
2517362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2518362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   switch (i->tag) {
2519362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_LI:
2520362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         p = mkLoadImm(p, iregNo(i->Min.LI.dst, mode64), i->Min.LI.imm, mode64);
2521362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
2522b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
2523362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Alu: {
2524362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         MIPSRH *srcR = i->Min.Alu.srcR;
2525362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         Bool immR = toBool(srcR->tag == Mrh_Imm);
2526362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_dst = iregNo(i->Min.Alu.dst, mode64);
2527362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_srcL = iregNo(i->Min.Alu.srcL, mode64);
2528b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         UInt r_srcR = immR ? (-1) /*bogus */ : iregNo(srcR->Mrh.Reg.reg,
2529b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                                                       mode64);
2530362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         switch (i->Min.Alu.op) {
2531b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            /* Malu_ADD, Malu_SUB, Malu_AND, Malu_OR, Malu_NOR, Malu_XOR, Malu_SLT */
2532362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Malu_ADD:
2533362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               if (immR) {
2534b181f371f0d30fd8d1e0dc0887831f0ac3d1af4bpetarj                  vassert(srcR->Mrh.Imm.syned);
2535b181f371f0d30fd8d1e0dc0887831f0ac3d1af4bpetarj                  /* addiu */
2536b181f371f0d30fd8d1e0dc0887831f0ac3d1af4bpetarj                  p = mkFormI(p, 9, r_srcL, r_dst, srcR->Mrh.Imm.imm16);
2537362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               } else {
2538362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  /* addu */
2539362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  p = mkFormR(p, 0, r_srcL, r_srcR, r_dst, 0, 33);
2540362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               }
2541362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
2542362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Malu_SUB:
2543362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               if (immR) {
2544b181f371f0d30fd8d1e0dc0887831f0ac3d1af4bpetarj                  /* addiu , but with negated imm */
2545362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  vassert(srcR->Mrh.Imm.syned);
2546362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  vassert(srcR->Mrh.Imm.imm16 != 0x8000);
2547b181f371f0d30fd8d1e0dc0887831f0ac3d1af4bpetarj                  p = mkFormI(p, 9, r_srcL, r_dst, (-srcR->Mrh.Imm.imm16));
2548362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               } else {
2549362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  /* subu */
2550362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  p = mkFormR(p, 0, r_srcL, r_srcR, r_dst, 0, 35);
2551362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               }
2552362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
2553362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Malu_AND:
2554362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               if (immR) {
2555362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  /* andi */
2556362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  vassert(!srcR->Mrh.Imm.syned);
2557362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  p = mkFormI(p, 12, r_srcL, r_dst, srcR->Mrh.Imm.imm16);
2558362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               } else {
2559362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  /* and */
2560362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  p = mkFormR(p, 0, r_srcL, r_srcR, r_dst, 0, 36);
2561362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               }
2562362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
2563362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Malu_OR:
2564362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               if (immR) {
2565362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  /* ori */
2566362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  vassert(!srcR->Mrh.Imm.syned);
2567362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  p = mkFormI(p, 13, r_srcL, r_dst, srcR->Mrh.Imm.imm16);
2568362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               } else {
2569362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  /* or */
2570362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  if (r_srcL == 33)
2571b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                     /* MFHI */
2572362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     p = mkFormR(p, 0, 0, 0, r_dst, 0, 16);
2573362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  else if (r_srcL == 34)
2574b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                     /* MFLO */
2575362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     p = mkFormR(p, 0, 0, 0, r_dst, 0, 18);
2576362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  else if (r_dst == 33)
2577b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                     /* MTHI */
2578362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     p = mkFormR(p, 0, r_srcL, 0, 0, 0, 17);
2579362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  else if (r_dst == 34)
2580b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                     /* MTLO */
2581362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     p = mkFormR(p, 0, r_srcL, 0, 0, 0, 19);
2582362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  else
2583362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     p = mkFormR(p, 0, r_srcL, r_srcR, r_dst, 0, 37);
2584362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               }
2585362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
2586362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Malu_NOR:
2587362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               /* nor */
2588362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               vassert(!immR);
2589362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0, r_srcL, r_srcR, r_dst, 0, 39);
2590362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
2591362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Malu_XOR:
2592362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               if (immR) {
2593362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  /* xori */
2594362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  vassert(!srcR->Mrh.Imm.syned);
2595362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  p = mkFormI(p, 14, r_srcL, r_dst, srcR->Mrh.Imm.imm16);
2596362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               } else {
2597362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  /* xor */
2598362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  p = mkFormR(p, 0, r_srcL, r_srcR, r_dst, 0, 38);
2599362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               }
2600362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
2601b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case Malu_DADD:
2602b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               if (immR) {
2603b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                  vassert(srcR->Mrh.Imm.syned);
2604b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                  vassert(srcR->Mrh.Imm.imm16 != 0x8000);
2605b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                  p = mkFormI(p, 25, r_srcL, r_dst, srcR->Mrh.Imm.imm16);
2606b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               } else {
2607b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                  p = mkFormR(p, 0, r_srcL, r_srcR, r_dst, 0, 45);
2608b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               }
2609b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               break;
2610b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case Malu_DSUB:
2611b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               if (immR) {
2612b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                  p = mkFormI(p, 25, r_srcL, r_dst, (-srcR->Mrh.Imm.imm16));
2613b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               } else {
2614b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                  p = mkFormR(p, 0, r_srcL, r_srcR, r_dst, 0, 47);
2615b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               }
2616b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               break;
2617b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case Malu_SLT:
2618b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               if (immR) {
2619b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                  goto bad;
2620b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               } else {
2621b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                  p = mkFormR(p, 0, r_srcL, r_srcR, r_dst, 0, 42);
2622b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               }
2623b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               break;
2624b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
2625362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            default:
2626362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               goto bad;
2627362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
2628362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
2629362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
2630362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2631362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Shft: {
2632362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         MIPSRH *srcR = i->Min.Shft.srcR;
2633362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         Bool sz32 = i->Min.Shft.sz32;
2634362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         Bool immR = toBool(srcR->tag == Mrh_Imm);
2635362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_dst = iregNo(i->Min.Shft.dst, mode64);
2636362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_srcL = iregNo(i->Min.Shft.srcL, mode64);
2637362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_srcR = immR ? (-1) /*bogus */ : iregNo(srcR->Mrh.Reg.reg,
2638362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                                                       mode64);
2639362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         if (!mode64)
2640362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            vassert(sz32);
2641362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         switch (i->Min.Shft.op) {
2642362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mshft_SLL:
2643362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               if (sz32) {
2644362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  if (immR) {
2645362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     UInt n = srcR->Mrh.Imm.imm16;
2646b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                     vassert(n >= 0 && n <= 32);
2647362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     p = mkFormS(p, 0, r_dst, 0, r_srcL, n, 0);
2648362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  } else {
2649362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     /* shift variable */
2650362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     p = mkFormS(p, 0, r_dst, r_srcR, r_srcL, 0, 4);
2651362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  }
2652362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               } else {
2653362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  if (immR) {
2654362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     UInt n = srcR->Mrh.Imm.imm16;
2655362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     vassert((n >= 0 && n < 32) || (n > 31 && n < 64));
2656362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     if (n >= 0 && n < 32) {
2657362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                        p = mkFormS(p, 0, r_dst, 0, r_srcL, n, 56);
2658362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     } else {
2659362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                        p = mkFormS(p, 0, r_dst, 0, r_srcL, n - 32, 60);
2660362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     }
2661362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  } else {
2662362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     p = mkFormS(p, 0, r_dst, r_srcR, r_srcL, 0, 20);
2663362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  }
2664362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               }
2665362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
2666b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
2667362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mshft_SRL:
2668362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               if (sz32) {
2669b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                  /* SRL, SRLV */
2670362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  if (immR) {
2671362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     UInt n = srcR->Mrh.Imm.imm16;
2672362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     vassert(n >= 0 && n < 32);
2673362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     p = mkFormS(p, 0, r_dst, 0, r_srcL, n, 2);
2674362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  } else {
2675362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     /* shift variable */
2676362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     p = mkFormS(p, 0, r_dst, r_srcR, r_srcL, 0, 6);
2677362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  }
2678362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               } else {
2679b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                  /* DSRL, DSRL32, DSRLV */
2680362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  if (immR) {
2681362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     UInt n = srcR->Mrh.Imm.imm16;
2682362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     vassert((n >= 0 && n < 32) || (n > 31 && n < 64));
2683362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     if (n >= 0 && n < 32) {
2684362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                        p = mkFormS(p, 0, r_dst, 0, r_srcL, n, 58);
2685362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     } else {
2686362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                        p = mkFormS(p, 0, r_dst, 0, r_srcL, n - 32, 62);
2687362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     }
2688362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  } else {
2689362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     p = mkFormS(p, 0, r_dst, r_srcR, r_srcL, 0, 22);
2690362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  }
2691362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               }
2692362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
2693b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
2694362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mshft_SRA:
2695362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               if (sz32) {
2696b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                  /* SRA, SRAV */
2697362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  if (immR) {
2698362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     UInt n = srcR->Mrh.Imm.imm16;
2699362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     vassert(n >= 0 && n < 32);
2700362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     p = mkFormS(p, 0, r_dst, 0, r_srcL, n, 3);
2701362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  } else {
2702362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     /* shift variable */
2703362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     p = mkFormS(p, 0, r_dst, r_srcR, r_srcL, 0, 7);
2704362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  }
2705362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               } else {
2706b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                  /* DSRA, DSRA32, DSRAV */
2707362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  if (immR) {
2708362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     UInt n = srcR->Mrh.Imm.imm16;
2709362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     vassert((n >= 0 && n < 32) || (n > 31 && n < 64));
2710362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     if (n >= 0 && n < 32) {
2711362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                        p = mkFormS(p, 0, r_dst, 0, r_srcL, n, 59);
2712362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     } else {
2713362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                        p = mkFormS(p, 0, r_dst, 0, r_srcL, n - 32, 63);
2714362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     }
2715362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  } else {
2716362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                     p = mkFormS(p, 0, r_dst, r_srcR, r_srcL, 0, 23);
2717362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  }
2718362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               }
2719362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
2720c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj
2721362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            default:
2722362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               goto bad;
2723362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
2724362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2725362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
2726362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
2727b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
2728362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Unary: {
2729362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_dst = iregNo(i->Min.Unary.dst, mode64);
2730362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_src = iregNo(i->Min.Unary.src, mode64);
2731362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2732362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         switch (i->Min.Unary.op) {
2733b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            /* Mun_CLO, Mun_CLZ, Mun_NOP, Mun_DCLO, Mun_DCLZ */
2734b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case Mun_CLO:  /* clo */
2735c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj               p = mkFormR(p, 28, r_src, r_dst , r_dst, 0, 33);
2736362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
2737b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case Mun_CLZ:  /* clz */
2738c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj               p = mkFormR(p, 28, r_src, r_dst , r_dst, 0, 32);
2739362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
2740b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case Mun_NOP:  /* nop (sll r0,r0,0) */
2741362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0, 0, 0, 0, 0, 0);
2742362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
2743b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case Mun_DCLO:  /* clo */
2744c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj               p = mkFormR(p, 28, r_src, r_dst , r_dst, 0, 37);
2745b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               break;
2746b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case Mun_DCLZ:  /* clz */
2747c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj               p = mkFormR(p, 28, r_src, r_dst , r_dst, 0, 36);
2748b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               break;
2749362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
2750362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
2751362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
2752b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
2753362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Cmp: {
2754362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_srcL = iregNo(i->Min.Cmp.srcL, mode64);
2755362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_srcR = iregNo(i->Min.Cmp.srcR, mode64);
2756362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_dst = iregNo(i->Min.Cmp.dst, mode64);
2757362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2758362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         switch (i->Min.Cmp.cond) {
2759362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case MIPScc_EQ:
2760a759d17f9b139ce17e9185291867fdeae3ad23efdejanj               /* xor r_dst, r_srcL, r_srcR
2761a759d17f9b139ce17e9185291867fdeae3ad23efdejanj                  sltiu r_dst, r_dst, 1 */
2762a759d17f9b139ce17e9185291867fdeae3ad23efdejanj               p = mkFormR(p, 0, r_srcL, r_srcR, r_dst, 0, 38);
2763a759d17f9b139ce17e9185291867fdeae3ad23efdejanj               p = mkFormI(p, 11, r_dst, r_dst, 1);
2764362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
2765362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case MIPScc_NE:
2766a759d17f9b139ce17e9185291867fdeae3ad23efdejanj               /* xor r_dst, r_srcL, r_srcR
2767a759d17f9b139ce17e9185291867fdeae3ad23efdejanj                  sltu r_dst, zero, r_dst */
2768a759d17f9b139ce17e9185291867fdeae3ad23efdejanj               p = mkFormR(p, 0, r_srcL, r_srcR, r_dst, 0, 38);
2769a759d17f9b139ce17e9185291867fdeae3ad23efdejanj               p = mkFormR(p, 0, 0, r_dst, r_dst, 0, 43);
2770362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
2771362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case MIPScc_LT:
2772b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               /* slt r_dst, r_srcL, r_srcR */
2773362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0, r_srcL, r_srcR, r_dst, 0, 42);
2774362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
2775362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case MIPScc_LO:
2776b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               /* sltu r_dst, r_srcL, r_srcR */
2777362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0, r_srcL, r_srcR, r_dst, 0, 43);
2778362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
2779362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case MIPScc_LE:
2780a759d17f9b139ce17e9185291867fdeae3ad23efdejanj               /* slt r_dst, r_srcR, r_srcL
2781a759d17f9b139ce17e9185291867fdeae3ad23efdejanj                  xori r_dst, r_dst, 1 */
2782a759d17f9b139ce17e9185291867fdeae3ad23efdejanj               p = mkFormR(p, 0, r_srcR, r_srcL, r_dst, 0, 42);
2783a759d17f9b139ce17e9185291867fdeae3ad23efdejanj               p = mkFormI(p, 14, r_dst, r_dst, 1);
2784362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
2785362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case MIPScc_LS:
2786a759d17f9b139ce17e9185291867fdeae3ad23efdejanj               /* sltu r_dst, rsrcR, r_srcL
2787a759d17f9b139ce17e9185291867fdeae3ad23efdejanj                  xori r_dsr, r_dst, 1 */
2788a759d17f9b139ce17e9185291867fdeae3ad23efdejanj               p = mkFormR(p, 0, r_srcR, r_srcL, r_dst, 0, 43);
2789a759d17f9b139ce17e9185291867fdeae3ad23efdejanj               p = mkFormI(p, 14, r_dst, r_dst, 1);
2790362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
2791362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            default:
2792362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               goto bad;
2793362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
2794362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
2795362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
2796b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
2797362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Mul: {
2798362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         Bool syned = i->Min.Mul.syned;
2799362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         Bool widening = i->Min.Mul.widening;
2800362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         Bool sz32 = i->Min.Mul.sz32;
2801362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_srcL = iregNo(i->Min.Mul.srcL, mode64);
2802362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_srcR = iregNo(i->Min.Mul.srcR, mode64);
2803362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_dst = iregNo(i->Min.Mul.dst, mode64);
2804362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         if (widening) {
2805362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            if (sz32) {
2806362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               if (syned)
2807362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  /* mult */
2808362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  p = mkFormR(p, 0, r_srcL, r_srcR, 0, 0, 24);
2809362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               else
2810362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  /* multu */
2811362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  p = mkFormR(p, 0, r_srcL, r_srcR, 0, 0, 25);
2812362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            } else {
2813362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               if (syned)  /* DMULT  r_dst,r_srcL,r_srcR */
2814362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  p = mkFormR(p, 0, r_srcL, r_srcR, 0, 0, 28);
2815362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               else  /* DMULTU r_dst,r_srcL,r_srcR */
2816362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  p = mkFormR(p, 0, r_srcL, r_srcR, 0, 0, 29);
2817362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
2818362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         } else {
2819362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            if (sz32)
2820362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               /* mul */
2821362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 28, r_srcL, r_srcR, r_dst, 0, 2);
2822362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            else if (mode64 && !sz32)
2823362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 28, r_srcL, r_srcR, r_dst, 0, 2);
2824362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            else
2825362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               goto bad;
2826362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
2827362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
2828362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
2829b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
2830362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Macc: {
2831362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         Bool syned = i->Min.Macc.syned;
2832362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_srcL = iregNo(i->Min.Macc.srcL, mode64);
2833362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_srcR = iregNo(i->Min.Macc.srcR, mode64);
2834362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2835362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         if (syned) {
2836362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            switch (i->Min.Macc.op) {
2837362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               case Macc_ADD:
2838b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                  /* madd */
2839362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  p = mkFormR(p, 28, r_srcL, r_srcR, 0, 0, 0);
2840362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  break;
2841362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               case Macc_SUB:
2842b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                  /* msub */
2843362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  p = mkFormR(p, 28, r_srcL, r_srcR, 0, 0,
2844362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                         4);
2845362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  break;
2846362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               default:
2847362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  goto bad;
2848362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
2849362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         } else {
2850362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            switch (i->Min.Macc.op) {
2851362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               case Macc_ADD:
2852b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                  /* maddu */
2853362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  p = mkFormR(p, 28, r_srcL, r_srcR, 0, 0,
2854362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                         1);
2855362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  break;
2856362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               case Macc_SUB:
2857b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                  /* msubu */
2858362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  p = mkFormR(p, 28, r_srcL, r_srcR, 0, 0,
2859362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                         5);
2860362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  break;
2861362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               default:
2862362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  goto bad;
2863362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
2864362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
2865362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2866362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
2867362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
2868362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2869362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Div: {
2870362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         Bool syned = i->Min.Div.syned;
2871362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         Bool sz32 = i->Min.Div.sz32;
2872362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_srcL = iregNo(i->Min.Div.srcL, mode64);
2873362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_srcR = iregNo(i->Min.Div.srcR, mode64);
2874362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         if (sz32) {
2875362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            if (syned) {
2876362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               /* div */
2877362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0, r_srcL, r_srcR, 0, 0, 26);
2878362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            } else
2879362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               /* divu */
2880362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0, r_srcL, r_srcR, 0, 0, 27);
2881362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            goto done;
2882362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         } else {
2883362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            if (syned) {
2884362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               /* ddiv */
2885362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0, r_srcL, r_srcR, 0, 0, 30);
2886362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            } else
2887362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               /* ddivu */
2888362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0, r_srcL, r_srcR, 0, 0, 31);
2889362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            goto done;
2890362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
2891362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
2892b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
2893362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Mthi: {
2894362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_src = iregNo(i->Min.MtHL.src, mode64);
2895362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         p = mkFormR(p, 0, r_src, 0, 0, 0, 17);
2896362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
2897362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
2898b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
2899362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Mtlo: {
2900362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_src = iregNo(i->Min.MtHL.src, mode64);
2901362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         p = mkFormR(p, 0, r_src, 0, 0, 0, 19);
2902362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
2903362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
2904b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
2905362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Mfhi: {
2906362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_dst = iregNo(i->Min.MfHL.dst, mode64);
2907362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         p = mkFormR(p, 0, 0, 0, r_dst, 0, 16);
2908362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
2909362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
2910b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
2911362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Mflo: {
2912362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_dst = iregNo(i->Min.MfHL.dst, mode64);
2913362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         p = mkFormR(p, 0, 0, 0, r_dst, 0, 18);
2914362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
2915362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
2916b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
2917362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_MtFCSR: {
2918362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_src = iregNo(i->Min.MtFCSR.src, mode64);
2919362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* ctc1 */
2920362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         p = mkFormR(p, 17, 6, r_src, 31, 0, 0);
2921362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
2922362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
2923b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
2924362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_MfFCSR: {
2925362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_dst = iregNo(i->Min.MfFCSR.dst, mode64);
2926362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* cfc1 */
2927362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         p = mkFormR(p, 17, 2, r_dst, 31, 0, 0);
2928362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
2929362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
2930b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
2931362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Call: {
293274142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj         if (i->Min.Call.cond != MIPScc_AL
293374142b8c8d5d3b3db17d744f5d5fb80f548bcf74sewardj             && i->Min.Call.rloc.pri != RLPri_None) {
2934cfe046e178666280b87da998b1b52ecda03ecd89sewardj            /* The call might not happen (it isn't unconditional) and
2935cfe046e178666280b87da998b1b52ecda03ecd89sewardj               it returns a result.  In this case we will need to
2936cfe046e178666280b87da998b1b52ecda03ecd89sewardj               generate a control flow diamond to put 0x555..555 in
2937cfe046e178666280b87da998b1b52ecda03ecd89sewardj               the return register(s) in the case where the call
2938cfe046e178666280b87da998b1b52ecda03ecd89sewardj               doesn't happen.  If this ever becomes necessary, maybe
2939cfe046e178666280b87da998b1b52ecda03ecd89sewardj               copy code from the ARM equivalent.  Until that day,
2940cfe046e178666280b87da998b1b52ecda03ecd89sewardj               just give up. */
2941cfe046e178666280b87da998b1b52ecda03ecd89sewardj            goto bad;
2942cfe046e178666280b87da998b1b52ecda03ecd89sewardj         }
2943362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         MIPSCondCode cond = i->Min.Call.cond;
2944c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj         UInt r_dst = 25;  /* using %r25 as address temporary -
2945b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                              see getRegUsage_MIPSInstr */
2946362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2947362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* jump over the following insns if condition does not hold */
2948362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         if (cond != MIPScc_AL) {
2949362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            /* jmp fwds if !condition */
2950362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            /* don't know how many bytes to jump over yet...
2951362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               make space for a jump instruction + nop!!! and fill in later. */
2952b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            ptmp = p;  /* fill in this bit later */
2953b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            p += 8;    /* p += 8 */
2954b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         }
2955b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
2956b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         if (!mode64) {
2957b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            /* addiu $29, $29, -16 */
2958b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            p = mkFormI(p, 9, 29, 29, 0xFFF0);
2959362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
2960362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2961b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         /* load target to r_dst; p += 4|8 */
2962362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         p = mkLoadImm(p, r_dst, i->Min.Call.target, mode64);
2963362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2964b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         /* jalr r_dst */
2965b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         p = mkFormR(p, 0, r_dst, 0, 31, 0, 9);  /* p += 4 */
2966b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         p = mkFormR(p, 0, 0, 0, 0, 0, 0);       /* p += 4 */
2967b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
2968b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         if (!mode64) {
2969b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            /* addiu $29, $29, 16 */
2970b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            p = mkFormI(p, 9, 29, 29, 0x0010);
2971b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         }
2972362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2973362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* Fix up the conditional jump, if there was one. */
2974362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         if (cond != MIPScc_AL) {
2975362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            UInt r_src = iregNo(i->Min.Call.src, mode64);
2976362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            Int delta = p - ptmp;
2977362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2978362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            vassert(delta >= 20 && delta <= 32);
2979b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            /* blez r_src, delta/4-1
2980b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               nop */
2981362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            ptmp = mkFormI(ptmp, 6, r_src, 0, delta / 4 - 1);
2982a81d9beb7bf438f460c582d6dbb53b5a08c4f8b4petarj            mkFormR(ptmp, 0, 0, 0, 0, 0, 0);
2983362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
2984362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
2985362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
2986362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2987362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_XDirect: {
2988362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* NB: what goes on here has to be very closely coordinated
2989362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            with the chainXDirect_MIPS and unchainXDirect_MIPS below. */
2990362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* We're generating chain-me requests here, so we need to be
2991362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            sure this is actually allowed -- no-redir translations
2992362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            can't use chain-me's.  Hence: */
2993362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vassert(disp_cp_chain_me_to_slowEP != NULL);
2994362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vassert(disp_cp_chain_me_to_fastEP != NULL);
2995362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2996362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* Use ptmp for backpatching conditional jumps. */
2997362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ptmp = NULL;
2998362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
2999362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* First off, if this is conditional, create a conditional
3000362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            jump over the rest of it.  Or at least, leave a space for
3001362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            it that we will shortly fill in. */
3002362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         if (i->Min.XDirect.cond != MIPScc_AL) {
3003362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            vassert(i->Min.XDirect.cond != MIPScc_NV);
3004362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            ptmp = p;
3005362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            p += 12;
3006362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
3007362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3008362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* Update the guest PC. */
3009362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* move r9, dstGA */
3010b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         /* sw/sd r9, amPC */
3011b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         p = mkLoadImm_EXACTLY2or6(p, /*r*/ 9, (ULong)i->Min.XDirect.dstGA,
3012b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                                   mode64);
3013b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         p = do_load_or_store_machine_word(p, False /*!isLoad*/ , /*r*/ 9,
3014b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                                           i->Min.XDirect.amPC, mode64);
3015362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3016362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* --- FIRST PATCHABLE BYTE follows --- */
3017362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* VG_(disp_cp_chain_me_to_{slowEP,fastEP}) (where we're
3018362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            calling to) backs up the return address, so as to find the
3019362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            address of the first patchable byte.  So: don't change the
3020362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            number of instructions (3) below. */
3021362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* move r9, VG_(disp_cp_chain_me_to_{slowEP,fastEP}) */
3022362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* jr  r9  */
30238462d113e3efeacceb304222dada8d85f748295aflorian         const void* disp_cp_chain_me
3024c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj                  = i->Min.XDirect.toFastEP ? disp_cp_chain_me_to_fastEP
3025362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                                              : disp_cp_chain_me_to_slowEP;
3026b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         p = mkLoadImm_EXACTLY2or6(p, /*r*/ 9,
302793a09742b0de3d61718882c2d999f64be402564dflorian                                   (Addr)disp_cp_chain_me, mode64);
3028362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* jalr $9 */
3029362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* nop */
3030b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         p = mkFormR(p, 0, 9, 0, 31, 0, 9);  /* p += 4 */
3031b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         p = mkFormR(p, 0, 0, 0, 0, 0, 0);   /* p += 4 */
3032362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* --- END of PATCHABLE BYTES --- */
3033362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3034362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* Fix up the conditional jump, if there was one. */
3035362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         if (i->Min.XDirect.cond != MIPScc_AL) {
3036362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            Int delta = p - ptmp;
3037362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            delta = delta / 4 - 3;
3038362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            vassert(delta > 0 && delta < 40);
3039b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
3040b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            /* lw $9, COND_OFFSET(GuestSP)
3041362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               beq $9, $0, 2
3042b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               nop */
3043b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            ptmp = mkFormI(ptmp, 35, GuestSP, 9, COND_OFFSET(mode64));
3044362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            ptmp = mkFormI(ptmp, 4, 0, 9, (delta));
3045a81d9beb7bf438f460c582d6dbb53b5a08c4f8b4petarj            mkFormR(ptmp, 0, 0, 0, 0, 0, 0);
3046362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
3047362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
3048362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
3049362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3050362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_XIndir: {
3051362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* We're generating transfers that could lead indirectly to a
3052362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            chain-me, so we need to be sure this is actually allowed --
3053362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            no-redir translations are not allowed to reach normal
3054362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            translations without going through the scheduler.  That means
3055362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            no XDirects or XIndirs out from no-redir translations.
3056362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            Hence: */
3057362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vassert(disp_cp_xindir != NULL);
3058362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3059362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* Use ptmp for backpatching conditional jumps. */
3060362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ptmp = NULL;
3061362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3062362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* First off, if this is conditional, create a conditional
3063362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            jump over the rest of it. */
3064362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         if (i->Min.XIndir.cond != MIPScc_AL) {
3065362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            vassert(i->Min.XIndir.cond != MIPScc_NV);
3066362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            ptmp = p;
3067362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            p += 12;
3068362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
3069362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3070362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* Update the guest PC. */
30710c30de83fbcb0f485c34c60f64e2994eaff37875petarj         /* sw/sd r-dstGA, amPC */
3072b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         p = do_load_or_store_machine_word(p, False /*!isLoad*/ ,
3073362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                                           iregNo(i->Min.XIndir.dstGA, mode64),
3074362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                                           i->Min.XIndir.amPC, mode64);
3075362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3076362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* move r9, VG_(disp_cp_xindir) */
3077362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* jalr   r9 */
3078362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* nop */
3079b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         p = mkLoadImm_EXACTLY2or6(p, /*r*/ 9,
308093a09742b0de3d61718882c2d999f64be402564dflorian                                   (Addr)disp_cp_xindir, mode64);
3081b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         p = mkFormR(p, 0, 9, 0, 31, 0, 9);  /* p += 4 */
3082b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         p = mkFormR(p, 0, 0, 0, 0, 0, 0);   /* p += 4 */
3083362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3084362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* Fix up the conditional jump, if there was one. */
3085362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         if (i->Min.XIndir.cond != MIPScc_AL) {
3086362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            Int delta = p - ptmp;
3087362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            delta = delta / 4 - 3;
3088362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            vassert(delta > 0 && delta < 40);
3089b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
3090b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            /* lw $9, COND_OFFSET($GuestSP)
3091362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               beq $9, $0, 2
3092b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               nop */
3093b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            ptmp = mkFormI(ptmp, 35, GuestSP, 9, COND_OFFSET(mode64));
3094362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            ptmp = mkFormI(ptmp, 4, 0, 9, (delta));
3095a81d9beb7bf438f460c582d6dbb53b5a08c4f8b4petarj            mkFormR(ptmp, 0, 0, 0, 0, 0, 0);
3096362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
3097362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
3098362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
3099362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3100362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_XAssisted: {
3101362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* First off, if this is conditional, create a conditional jump
3102362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            over the rest of it.  Or at least, leave a space for it that
3103362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            we will shortly fill in. */
3104362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         ptmp = NULL;
3105362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         if (i->Min.XAssisted.cond != MIPScc_AL) {
3106362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            vassert(i->Min.XAssisted.cond != MIPScc_NV);
3107362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            ptmp = p;
3108362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            p += 12;
3109362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
3110362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3111362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* Update the guest PC. */
3112b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         /* sw/sd r-dstGA, amPC */
3113b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         p = do_load_or_store_machine_word(p, False /*!isLoad*/ ,
3114362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                                           iregNo(i->Min.XIndir.dstGA, mode64),
3115362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                                           i->Min.XIndir.amPC, mode64);
3116362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3117362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* imm32/64 r31, $magic_number */
3118362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt trcval = 0;
3119362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         switch (i->Min.XAssisted.jk) {
3120a6a1986ba221f6c827662b57a7e4ef8206093475petarj            case Ijk_ClientReq:     trcval = VEX_TRC_JMP_CLIENTREQ;     break;
3121a6a1986ba221f6c827662b57a7e4ef8206093475petarj            case Ijk_Sys_syscall:   trcval = VEX_TRC_JMP_SYS_SYSCALL;   break;
31226ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj            /* case Ijk_Sys_int128: trcval = VEX_TRC_JMP_SYS_INT128;   break; */
31236ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj            case Ijk_Yield:         trcval = VEX_TRC_JMP_YIELD;       break;
3124a6a1986ba221f6c827662b57a7e4ef8206093475petarj            case Ijk_EmWarn:        trcval = VEX_TRC_JMP_EMWARN;        break;
3125a6a1986ba221f6c827662b57a7e4ef8206093475petarj            case Ijk_EmFail:        trcval = VEX_TRC_JMP_EMFAIL;        break;
3126b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            /* case Ijk_MapFail:   trcval = VEX_TRC_JMP_MAPFAIL;       break; */
3127a6a1986ba221f6c827662b57a7e4ef8206093475petarj            case Ijk_NoDecode:      trcval = VEX_TRC_JMP_NODECODE;      break;
312805f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj            case Ijk_InvalICache:   trcval = VEX_TRC_JMP_INVALICACHE;   break;
3129a6a1986ba221f6c827662b57a7e4ef8206093475petarj            case Ijk_NoRedir:       trcval = VEX_TRC_JMP_NOREDIR;       break;
31300e006f25d4016d7845bd016b65b5d2676a4e8c92dejanj            case Ijk_SigILL:        trcval = VEX_TRC_JMP_SIGILL;        break;
3131a6a1986ba221f6c827662b57a7e4ef8206093475petarj            case Ijk_SigTRAP:       trcval = VEX_TRC_JMP_SIGTRAP;       break;
3132b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            /* case Ijk_SigSEGV:   trcval = VEX_TRC_JMP_SIGSEGV;       break; */
3133a6a1986ba221f6c827662b57a7e4ef8206093475petarj            case Ijk_SigBUS:        trcval = VEX_TRC_JMP_SIGBUS;        break;
3134a6a1986ba221f6c827662b57a7e4ef8206093475petarj            case Ijk_SigFPE_IntDiv: trcval = VEX_TRC_JMP_SIGFPE_INTDIV; break;
3135a6a1986ba221f6c827662b57a7e4ef8206093475petarj            case Ijk_SigFPE_IntOvf: trcval = VEX_TRC_JMP_SIGFPE_INTOVF; break;
3136a6a1986ba221f6c827662b57a7e4ef8206093475petarj            case Ijk_Boring:        trcval = VEX_TRC_JMP_BORING;        break;
3137b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            /* We don't expect to see the following being assisted.
3138b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               case Ijk_Ret:
3139b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               case Ijk_Call:
3140b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               fallthrough */
3141c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj            default:
3142362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               ppIRJumpKind(i->Min.XAssisted.jk);
3143362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               vpanic("emit_MIPSInstr.Min_XAssisted: unexpected jump kind");
3144362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
3145362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vassert(trcval != 0);
3146b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         p = mkLoadImm_EXACTLY2or6(p, /*r*/ GuestSP, trcval, mode64);
3147362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3148362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* move r9, VG_(disp_cp_xassisted) */
3149b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         p = mkLoadImm_EXACTLY2or6(p, /*r*/ 9,
315093a09742b0de3d61718882c2d999f64be402564dflorian                                   (ULong)(Addr)disp_cp_xassisted, mode64);
3151362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* jalr $9
3152362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj             nop */
3153b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         p = mkFormR(p, 0, 9, 0, 31, 0, 9);  /* p += 4 */
3154b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         p = mkFormR(p, 0, 0, 0, 0, 0, 0);   /* p += 4 */
3155362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3156362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* Fix up the conditional jump, if there was one. */
3157362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         if (i->Min.XAssisted.cond != MIPScc_AL) {
3158362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            Int delta = p - ptmp;
3159362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            delta = delta / 4 - 3;
3160362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            vassert(delta > 0 && delta < 40);
3161b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
3162b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            /* lw $9, COND_OFFSET($GuestSP)
3163362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               beq $9, $0, 2
3164b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               nop */
3165b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            ptmp = mkFormI(ptmp, 35, GuestSP, 9, COND_OFFSET(mode64));
3166362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            ptmp = mkFormI(ptmp, 4, 0, 9, (delta));
3167a81d9beb7bf438f460c582d6dbb53b5a08c4f8b4petarj            mkFormR(ptmp, 0, 0, 0, 0, 0, 0);
3168362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
3169362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
3170362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
3171362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3172362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Load: {
3173362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         MIPSAMode *am_addr = i->Min.Load.src;
3174362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         if (am_addr->tag == Mam_IR) {
3175362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            UInt r_dst = iregNo(i->Min.Load.dst, mode64);
3176362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            UInt opc, sz = i->Min.Load.sz;
3177362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            if (mode64 && (sz == 4 || sz == 8)) {
3178362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               /* should be guaranteed to us by iselWordExpr_AMode */
3179362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               vassert(0 == (am_addr->Mam.IR.index & 3));
3180362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
3181362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            switch (sz) {
3182362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               case 1:
3183362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  opc = 32;
3184362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  break;
3185362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               case 2:
3186362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  opc = 33;
3187362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  break;
3188362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               case 4:
3189362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  opc = 35;
3190362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  break;
3191362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               case 8:
3192362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  opc = 55;
3193362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  vassert(mode64);
3194362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  break;
3195362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               default:
3196362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  goto bad;
3197362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
3198362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3199362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            p = doAMode_IR(p, opc, r_dst, am_addr, mode64);
3200362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            goto done;
3201362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         } else if (am_addr->tag == Mam_RR) {
3202362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            UInt r_dst = iregNo(i->Min.Load.dst, mode64);
3203362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            UInt opc, sz = i->Min.Load.sz;
3204362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3205362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            switch (sz) {
3206362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               case 1:
3207362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  opc = 32;
3208362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  break;
3209362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               case 2:
3210362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  opc = 33;
3211362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  break;
3212362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               case 4:
3213362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  opc = 35;
3214362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  break;
3215362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               case 8:
3216362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  opc = 55;
3217362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  vassert(mode64);
3218362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  break;
3219362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               default:
3220362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  goto bad;
3221362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
3222362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3223362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            p = doAMode_RR(p, opc, r_dst, am_addr, mode64);
3224362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            goto done;
3225362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
3226362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
3227362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
3228b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
3229362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_Store: {
3230362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         MIPSAMode *am_addr = i->Min.Store.dst;
3231362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         if (am_addr->tag == Mam_IR) {
3232362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            UInt r_src = iregNo(i->Min.Store.src, mode64);
3233362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            UInt opc, sz = i->Min.Store.sz;
3234362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            if (mode64 && (sz == 4 || sz == 8)) {
3235362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               /* should be guaranteed to us by iselWordExpr_AMode */
3236362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               vassert(0 == (am_addr->Mam.IR.index & 3));
3237362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
3238362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            switch (sz) {
3239362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               case 1:
3240362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  opc = 40;
3241362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  break;
3242362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               case 2:
3243362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  opc = 41;
3244362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  break;
3245362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               case 4:
3246362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  opc = 43;
3247362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  break;
3248362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               case 8:
3249362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  vassert(mode64);
3250362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  opc = 63;
3251362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  break;
3252362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               default:
3253362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  goto bad;
3254362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
3255362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3256362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            p = doAMode_IR(p, opc, r_src, am_addr, mode64);
3257362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            goto done;
3258362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         } else if (am_addr->tag == Mam_RR) {
3259362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            UInt r_src = iregNo(i->Min.Store.src, mode64);
3260362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            UInt opc, sz = i->Min.Store.sz;
3261362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3262362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            switch (sz) {
3263362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               case 1:
3264362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  opc = 40;
3265362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  break;
3266362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               case 2:
3267362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  opc = 41;
3268362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  break;
3269362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               case 4:
3270362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  opc = 43;
3271362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  break;
3272362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               case 8:
3273362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  vassert(mode64);
3274362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  opc = 63;
3275362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  break;
3276362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               default:
3277362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  goto bad;
3278362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
3279362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3280362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            p = doAMode_RR(p, opc, r_src, am_addr, mode64);
3281362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            goto done;
3282362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
3283362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         break;
3284362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
3285362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_LoadL: {
3286362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         MIPSAMode *am_addr = i->Min.LoadL.src;
3287362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_src = iregNo(am_addr->Mam.IR.base, mode64);
3288362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt idx = am_addr->Mam.IR.index;
3289362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_dst = iregNo(i->Min.LoadL.dst, mode64);
3290362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3291b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         if (i->Min.LoadL.sz == 4)
3292b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            p = mkFormI(p, 0x30, r_src, r_dst, idx);
3293b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         else
3294b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            p = mkFormI(p, 0x34, r_src, r_dst, idx);
3295362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
3296362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
3297362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_StoreC: {
3298362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         MIPSAMode *am_addr = i->Min.StoreC.dst;
3299362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_src = iregNo(i->Min.StoreC.src, mode64);
3300362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt idx = am_addr->Mam.IR.index;
3301362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt r_dst = iregNo(am_addr->Mam.IR.base, mode64);
3302362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3303b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         if (i->Min.StoreC.sz == 4)
3304b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            p = mkFormI(p, 0x38, r_dst, r_src, idx);
3305b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         else
3306b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            p = mkFormI(p, 0x3C, r_dst, r_src, idx);
3307362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
3308362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
33096ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj      case Min_Cas: {
33106ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         if (i->Min.Cas.sz != 8 && i->Min.Cas.sz != 4)
33116ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj            goto bad;
33126ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         UInt old  = iregNo(i->Min.Cas.old, mode64);
33136ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         UInt addr = iregNo(i->Min.Cas.addr, mode64);
33146ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         UInt expd = iregNo(i->Min.Cas.expd, mode64);
33156ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         UInt data = iregNo(i->Min.Cas.data, mode64);
33166ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         Bool sz8  = toBool(i->Min.Cas.sz == 8);
33176ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj
33186ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         /*
33196ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj          * ll(d)    old,  0(addr)
33206ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj          * bne      old,  expd, end
33216ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj          * nop
33226ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj          * (d)addiu old,  old,  1
33236ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj          * sc(d)    data, 0(addr)
33246ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj          * movn     old,  expd, data
33256ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj          * end:
33266ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj          */
33276ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         // ll(d) old, 0(addr)
33286ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         p = mkFormI(p, sz8 ? 0x34 : 0x30, addr, old, 0);
33296ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         // bne  old,  expd, end
33306ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         p = mkFormI(p, 5, old, expd, 4);
33316ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         // nop
33326ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         p = mkFormR(p, 0, 0, 0, 0, 0, 0);
33336ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         // (d)addiu old,  old,  1
33346ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         p = mkFormI(p, sz8 ? 25 : 9, old, old, 1);
33356ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         // sc(d)  data, 0(addr)
33366ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         p = mkFormI(p, sz8 ? 0x3C : 0x38, addr, data, 0);
33376ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         // movn old,  expd, data
33386ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         p = mkFormR(p, 0, expd, data, old, 0, 0xb);
33396ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj
33406ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj         goto done;
33416ced72b3286a45a9fd05989a1e13c0ac5b911feedejanj      }
3342362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_RdWrLR: {
3343362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt reg = iregNo(i->Min.RdWrLR.gpr, mode64);
3344362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         Bool wrLR = i->Min.RdWrLR.wrLR;
3345362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         if (wrLR)
3346362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            p = mkMoveReg(p, 31, reg);
3347362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         else
3348362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            p = mkMoveReg(p, reg, 31);
3349362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
3350362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
3351b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
3352b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      /* Floating point */
3353362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_FpLdSt: {
3354362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         MIPSAMode *am_addr = i->Min.FpLdSt.addr;
3355362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UChar sz = i->Min.FpLdSt.sz;
3356362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vassert(sz == 4 || sz == 8);
3357362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         if (sz == 4) {
3358362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            UInt f_reg = fregNo(i->Min.FpLdSt.reg, mode64);
3359362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            if (i->Min.FpLdSt.isLoad) {
3360362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               if (am_addr->tag == Mam_IR)
3361362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  p = doAMode_IR(p, 0x31, f_reg, am_addr, mode64);
3362362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               else if (am_addr->tag == Mam_RR)
3363362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  p = doAMode_RR(p, 0x31, f_reg, am_addr, mode64);
3364362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            } else {
3365362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               if (am_addr->tag == Mam_IR)
3366362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  p = doAMode_IR(p, 0x39, f_reg, am_addr, mode64);
3367362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               else if (am_addr->tag == Mam_RR)
3368362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                  p = doAMode_RR(p, 0x39, f_reg, am_addr, mode64);
3369362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
3370362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         } else if (sz == 8) {
3371362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            UInt f_reg = dregNo(i->Min.FpLdSt.reg);
3372362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            if (i->Min.FpLdSt.isLoad) {
3373362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               if (am_addr->tag == Mam_IR) {
33741ec43e09fe3d870c3dfd3d1f4eb8198cbaf91370petarj                  p = doAMode_IR(p, 0x35, f_reg, am_addr, mode64);
3375362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               } else if (am_addr->tag == Mam_RR) {
33761ec43e09fe3d870c3dfd3d1f4eb8198cbaf91370petarj                  p = doAMode_RR(p, 0x35, f_reg, am_addr, mode64);
3377362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               }
3378362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            } else {
3379362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               if (am_addr->tag == Mam_IR) {
33801ec43e09fe3d870c3dfd3d1f4eb8198cbaf91370petarj                  p = doAMode_IR(p, 0x3d, f_reg, am_addr, mode64);
3381362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               } else if (am_addr->tag == Mam_RR) {
33821ec43e09fe3d870c3dfd3d1f4eb8198cbaf91370petarj                  p = doAMode_RR(p, 0x3d, f_reg, am_addr, mode64);
3383362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               }
3384362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
3385362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
3386362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
3387362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
3388362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3389362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_FpUnary: {
3390362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         switch (i->Min.FpUnary.op) {
3391b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case Mfp_MOVS: {  /* FP move */
3392362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_dst = fregNo(i->Min.FpUnary.dst, mode64);
3393362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_src = fregNo(i->Min.FpUnary.src, mode64);
3394362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x10, 0, fr_src, fr_dst, 0x6);
3395362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3396362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
3397b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case Mfp_MOVD: {  /* FP move */
3398362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                UInt fr_dst = dregNo(i->Min.FpUnary.dst);
3399362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                UInt fr_src = dregNo(i->Min.FpUnary.src);
3400362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                p = mkFormR(p, 0x11, 0x11, 0, fr_src, fr_dst, 0x6);
3401362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                break;
3402362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj             }
3403c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj            case Mfp_ABSS: {  /* ABS.S */
3404362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_dst = fregNo(i->Min.FpUnary.dst, mode64);
3405362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_src = fregNo(i->Min.FpUnary.src, mode64);
3406362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x10, 0, fr_src, fr_dst, 0x5);
3407362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3408362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
3409c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj            case Mfp_ABSD: {  /* ABS.D */
3410362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_dst = dregNo(i->Min.FpUnary.dst);
3411362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_src = dregNo(i->Min.FpUnary.src);
3412362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x11, 0, fr_src, fr_dst, 0x5);
3413362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3414362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
3415c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj            case Mfp_NEGS: {  /* NEG.S */
3416362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_dst = fregNo(i->Min.FpUnary.dst, mode64);
3417362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_src = fregNo(i->Min.FpUnary.src, mode64);
3418362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x10, 0, fr_src, fr_dst, 0x7);
3419362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3420362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
3421c3fee0debd7287a8c6a3b89ee6bc1ec58241938bdejanj            case Mfp_NEGD: {  /* NEG.D */
3422362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_dst = dregNo(i->Min.FpUnary.dst);
3423362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_src = dregNo(i->Min.FpUnary.src);
3424362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x11, 0, fr_src, fr_dst, 0x7);
3425362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3426362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
3427b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case Mfp_SQRTS: {  /* SQRT.S */
3428362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_dst = fregNo(i->Min.FpUnary.dst, mode64);
3429362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_src = fregNo(i->Min.FpUnary.src, mode64);
3430362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x10, 0, fr_src, fr_dst, 0x04);
3431362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3432362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
3433b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case Mfp_SQRTD: {  /* SQRT.D */
3434362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_dst = dregNo(i->Min.FpUnary.dst);
3435362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_src = dregNo(i->Min.FpUnary.src);
3436362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x11, 0, fr_src, fr_dst, 0x04);
3437362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3438362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
3439362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            default:
3440362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               goto bad;
3441362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
3442362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
3443362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
3444362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3445362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_FpBinary: {
3446362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         switch (i->Min.FpBinary.op) {
3447362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mfp_ADDS: {
3448362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_dst = fregNo(i->Min.FpBinary.dst, mode64);
3449362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_srcL = fregNo(i->Min.FpBinary.srcL, mode64);
3450362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_srcR = fregNo(i->Min.FpBinary.srcR, mode64);
3451362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x10, fr_srcR, fr_srcL, fr_dst, 0);
3452362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3453362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
3454362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mfp_SUBS: {
3455362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_dst = fregNo(i->Min.FpBinary.dst, mode64);
3456362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_srcL = fregNo(i->Min.FpBinary.srcL, mode64);
3457362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_srcR = fregNo(i->Min.FpBinary.srcR, mode64);
3458362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x10, fr_srcR, fr_srcL, fr_dst, 1);
3459362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3460362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
3461362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mfp_MULS: {
3462362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_dst = fregNo(i->Min.FpBinary.dst, mode64);
3463362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_srcL = fregNo(i->Min.FpBinary.srcL, mode64);
3464362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_srcR = fregNo(i->Min.FpBinary.srcR, mode64);
3465362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x10, fr_srcR, fr_srcL, fr_dst, 2);
3466362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3467362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
3468362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mfp_DIVS: {
3469362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_dst = fregNo(i->Min.FpBinary.dst, mode64);
3470362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_srcL = fregNo(i->Min.FpBinary.srcL, mode64);
3471362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_srcR = fregNo(i->Min.FpBinary.srcR, mode64);
3472362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x10, fr_srcR, fr_srcL, fr_dst, 3);
3473362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3474362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
3475362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mfp_ADDD: {
3476362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_dst = dregNo(i->Min.FpBinary.dst);
3477362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_srcL = dregNo(i->Min.FpBinary.srcL);
3478362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_srcR = dregNo(i->Min.FpBinary.srcR);
3479362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x11, fr_srcR, fr_srcL, fr_dst, 0);
3480362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3481362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
3482362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mfp_SUBD: {
3483362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_dst = dregNo(i->Min.FpBinary.dst);
3484362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_srcL = dregNo(i->Min.FpBinary.srcL);
3485362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_srcR = dregNo(i->Min.FpBinary.srcR);
3486362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x11, fr_srcR, fr_srcL, fr_dst, 1);
3487362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3488362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
3489362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mfp_MULD: {
3490362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_dst = dregNo(i->Min.FpBinary.dst);
3491362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_srcL = dregNo(i->Min.FpBinary.srcL);
3492362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_srcR = dregNo(i->Min.FpBinary.srcR);
3493362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x11, fr_srcR, fr_srcL, fr_dst, 2);
3494362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3495362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
3496362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mfp_DIVD: {
3497362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_dst = dregNo(i->Min.FpBinary.dst);
3498362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_srcL = dregNo(i->Min.FpBinary.srcL);
3499362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               UInt fr_srcR = dregNo(i->Min.FpBinary.srcR);
3500362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x11, fr_srcR, fr_srcL, fr_dst, 3);
3501362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3502362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            }
3503362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            default:
3504362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               goto bad;
3505362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
3506362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
3507362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
3508362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3509b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case Min_FpTernary: {
3510b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         switch (i->Min.FpTernary.op) {
3511b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case Mfp_MADDS: {
3512b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               UInt fr_dst = fregNo(i->Min.FpTernary.dst, mode64);
3513b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               UInt fr_src1 = fregNo(i->Min.FpTernary.src1, mode64);
3514b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               UInt fr_src2 = fregNo(i->Min.FpTernary.src2, mode64);
3515b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               UInt fr_src3 = fregNo(i->Min.FpTernary.src3, mode64);
3516b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               p = mkFormR(p, 0x13, fr_src1, fr_src2, fr_src3, fr_dst, 0x20);
3517b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               break;
3518b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            }
3519b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case Mfp_MADDD: {
3520b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               UInt fr_dst = dregNo(i->Min.FpTernary.dst);
3521b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               UInt fr_src1 = dregNo(i->Min.FpTernary.src1);
3522b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               UInt fr_src2 = dregNo(i->Min.FpTernary.src2);
3523b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               UInt fr_src3 = dregNo(i->Min.FpTernary.src3);
3524b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               p = mkFormR(p, 0x13, fr_src1, fr_src2, fr_src3, fr_dst, 0x21);
3525b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               break;
3526b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            }
3527b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case Mfp_MSUBS: {
3528b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               UInt fr_dst = fregNo(i->Min.FpTernary.dst, mode64);
3529b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               UInt fr_src1 = fregNo(i->Min.FpTernary.src1, mode64);
3530b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               UInt fr_src2 = fregNo(i->Min.FpTernary.src2, mode64);
3531b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               UInt fr_src3 = fregNo(i->Min.FpTernary.src3, mode64);
3532b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               p = mkFormR(p, 0x13, fr_src1, fr_src2, fr_src3, fr_dst, 0x28);
3533b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               break;
3534b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            }
3535b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case Mfp_MSUBD: {
3536b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               UInt fr_dst = dregNo(i->Min.FpTernary.dst);
3537b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               UInt fr_src1 = dregNo(i->Min.FpTernary.src1);
3538b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               UInt fr_src2 = dregNo(i->Min.FpTernary.src2);
3539b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               UInt fr_src3 = dregNo(i->Min.FpTernary.src3);
3540b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               p = mkFormR(p, 0x13, fr_src1, fr_src2, fr_src3, fr_dst, 0x29);
3541b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               break;
3542b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            }
3543b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            default:
3544b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               goto bad;
3545b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         }
3546b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         goto done;
3547b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      }
3548b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
3549362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_FpConvert: {
3550362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         switch (i->Min.FpConvert.op) {
3551362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            UInt fr_dst, fr_src;
3552362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mfp_CVTSD:
3553362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_dst = fregNo(i->Min.FpConvert.dst, mode64);
3554362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_src = dregNo(i->Min.FpConvert.src);
3555362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x11, 0, fr_src, fr_dst, 0x20);
3556362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3557362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mfp_CVTSW:
3558362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_dst = fregNo(i->Min.FpConvert.dst, mode64);
3559362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_src = fregNo(i->Min.FpConvert.src, mode64);
3560362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x14, 0, fr_src, fr_dst, 0x20);
3561362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3562362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mfp_CVTWD:
3563362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_dst = fregNo(i->Min.FpConvert.dst, mode64);
3564362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_src = dregNo(i->Min.FpConvert.src);
3565362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x11, 0, fr_src, fr_dst, 0x24);
3566362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3567362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mfp_CVTWS:
3568362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_dst = fregNo(i->Min.FpConvert.dst, mode64);
3569362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_src = fregNo(i->Min.FpConvert.src, mode64);
3570362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x10, 0, fr_src, fr_dst, 0x24);
3571362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3572362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mfp_CVTDW:
3573362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_dst = dregNo(i->Min.FpConvert.dst);
3574362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_src = fregNo(i->Min.FpConvert.src, mode64);
3575362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x14, 0, fr_src, fr_dst, 0x21);
3576362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3577b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case Mfp_CVTDL:
3578b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               fr_dst = dregNo(i->Min.FpConvert.dst);
3579b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               fr_src = dregNo(i->Min.FpConvert.src);
3580b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               p = mkFormR(p, 0x11, 0x15, 0, fr_src, fr_dst, 0x21);
3581b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               break;
3582b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case Mfp_CVTDS:
3583b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               fr_dst = dregNo(i->Min.FpConvert.dst);
3584b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               fr_src = fregNo(i->Min.FpConvert.src, mode64);
3585b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               p = mkFormR(p, 0x11, 0x10, 0, fr_src, fr_dst, 0x21);
3586b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               break;
3587b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case Mfp_CVTSL:
3588b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               fr_dst = dregNo(i->Min.FpConvert.dst);
3589b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               fr_src = fregNo(i->Min.FpConvert.src, mode64);
3590b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               p = mkFormR(p, 0x11, 0x15, 0, fr_src, fr_dst, 0x20);
3591b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               break;
3592b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case Mfp_CVTLS:
35930e006f25d4016d7845bd016b65b5d2676a4e8c92dejanj               if (mode64) {
35940e006f25d4016d7845bd016b65b5d2676a4e8c92dejanj                  fr_dst = fregNo(i->Min.FpConvert.dst, mode64);
35950e006f25d4016d7845bd016b65b5d2676a4e8c92dejanj                  fr_src = dregNo(i->Min.FpConvert.src);
35960e006f25d4016d7845bd016b65b5d2676a4e8c92dejanj               } else {
35970e006f25d4016d7845bd016b65b5d2676a4e8c92dejanj                  fr_dst = dregNo(i->Min.FpConvert.dst);
35980e006f25d4016d7845bd016b65b5d2676a4e8c92dejanj                  fr_src = fregNo(i->Min.FpConvert.src, mode64);
35990e006f25d4016d7845bd016b65b5d2676a4e8c92dejanj               }
3600b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               p = mkFormR(p, 0x11, 0x10, 0, fr_src, fr_dst, 0x25);
3601b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               break;
3602b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case Mfp_CVTLD:
3603b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               fr_dst = dregNo(i->Min.FpConvert.dst);
3604b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               fr_src = dregNo(i->Min.FpConvert.src);
3605b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               p = mkFormR(p, 0x11, 0x11, 0, fr_src, fr_dst, 0x25);
3606b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               break;
3607362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mfp_TRUWS:
3608362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_dst = fregNo(i->Min.FpConvert.dst, mode64);
3609362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_src = fregNo(i->Min.FpConvert.src, mode64);
3610362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x10, 0, fr_src, fr_dst, 0x0D);
3611362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3612362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mfp_TRUWD:
3613362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_dst = fregNo(i->Min.FpConvert.dst, mode64);
3614362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_src = dregNo(i->Min.FpConvert.src);
3615362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x11, 0, fr_src, fr_dst, 0x0D);
3616362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3617362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mfp_TRULS:
3618362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_dst = fregNo(i->Min.FpConvert.dst, mode64);
3619362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_src = dregNo(i->Min.FpConvert.src);
3620362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x10, 0, fr_src, fr_dst, 0x09);
3621362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3622362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mfp_TRULD:
3623362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_dst = dregNo(i->Min.FpConvert.dst);
3624362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_src = dregNo(i->Min.FpConvert.src);
3625362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x11, 0, fr_src, fr_dst, 0x09);
3626362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3627362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mfp_CEILWS:
3628362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_dst = fregNo(i->Min.FpConvert.dst, mode64);
3629362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_src = fregNo(i->Min.FpConvert.src, mode64);
3630362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x10, 0, fr_src, fr_dst, 0x0E);
3631362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3632362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mfp_CEILWD:
3633362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_dst = fregNo(i->Min.FpConvert.dst, mode64);
3634362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_src = dregNo(i->Min.FpConvert.src);
3635362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x11, 0, fr_src, fr_dst, 0x0E);
3636362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3637362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mfp_CEILLS:
3638362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_dst = dregNo(i->Min.FpConvert.dst);
3639362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_src = fregNo(i->Min.FpConvert.src, mode64);
3640362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x10, 0, fr_src, fr_dst, 0x0A);
3641362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3642362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mfp_CEILLD:
3643362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_dst = dregNo(i->Min.FpConvert.dst);
3644362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_src = dregNo(i->Min.FpConvert.src);
3645362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x11, 0, fr_src, fr_dst, 0x0A);
3646362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3647362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mfp_ROUNDWS:
3648362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_dst = fregNo(i->Min.FpConvert.dst, mode64);
3649362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_src = fregNo(i->Min.FpConvert.src, mode64);
3650362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x10, 0, fr_src, fr_dst, 0x0C);
3651362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3652362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mfp_ROUNDWD:
3653362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_dst = fregNo(i->Min.FpConvert.dst, mode64);
3654362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_src = dregNo(i->Min.FpConvert.src);
3655362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x11, 0, fr_src, fr_dst, 0x0C);
3656362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3657a759d17f9b139ce17e9185291867fdeae3ad23efdejanj            case Mfp_ROUNDLD:
3658a759d17f9b139ce17e9185291867fdeae3ad23efdejanj               fr_dst = dregNo(i->Min.FpConvert.dst);
3659a759d17f9b139ce17e9185291867fdeae3ad23efdejanj               fr_src = dregNo(i->Min.FpConvert.src);
3660a759d17f9b139ce17e9185291867fdeae3ad23efdejanj               p = mkFormR(p, 0x11, 0x11, 0, fr_src, fr_dst, 0x08);
3661a759d17f9b139ce17e9185291867fdeae3ad23efdejanj               break;
3662362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mfp_FLOORWS:
3663362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_dst = fregNo(i->Min.FpConvert.dst, mode64);
3664362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_src = fregNo(i->Min.FpConvert.src, mode64);
3665362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x10, 0, fr_src, fr_dst, 0x0F);
3666362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3667362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            case Mfp_FLOORWD:
3668362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_dst = fregNo(i->Min.FpConvert.dst, mode64);
3669362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               fr_src = dregNo(i->Min.FpConvert.src);
3670362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               p = mkFormR(p, 0x11, 0x11, 0, fr_src, fr_dst, 0x0F);
3671362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
36723bc88cc541ef33cea89e05c56e4c737451552f99dejanj            case Mfp_FLOORLD:
36733bc88cc541ef33cea89e05c56e4c737451552f99dejanj               fr_dst = dregNo(i->Min.FpConvert.dst);
36743bc88cc541ef33cea89e05c56e4c737451552f99dejanj               fr_src = dregNo(i->Min.FpConvert.src);
36753bc88cc541ef33cea89e05c56e4c737451552f99dejanj               p = mkFormR(p, 0x11, 0x11, 0, fr_src, fr_dst, 0x0B);
36763bc88cc541ef33cea89e05c56e4c737451552f99dejanj               break;
3677362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3678362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            default:
3679362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               goto bad;
3680362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
3681362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
3682362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
3683362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3684362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_FpCompare: {
3685f37c086134874a2ba372f6750a45466473a813b1dejanj         UInt r_dst   = iregNo(i->Min.FpCompare.dst, mode64);
3686362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt fr_srcL = dregNo(i->Min.FpCompare.srcL);
3687362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UInt fr_srcR = dregNo(i->Min.FpCompare.srcR);
3688362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3689f37c086134874a2ba372f6750a45466473a813b1dejanj         UInt op;
3690362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         switch (i->Min.FpConvert.op) {
3691f37c086134874a2ba372f6750a45466473a813b1dejanj            case Mfp_CMP_UN:
3692f37c086134874a2ba372f6750a45466473a813b1dejanj               op = 1;
3693f37c086134874a2ba372f6750a45466473a813b1dejanj               break;
3694f37c086134874a2ba372f6750a45466473a813b1dejanj            case Mfp_CMP_EQ:
3695f37c086134874a2ba372f6750a45466473a813b1dejanj               op = 2;
3696f37c086134874a2ba372f6750a45466473a813b1dejanj               break;
3697f37c086134874a2ba372f6750a45466473a813b1dejanj            case Mfp_CMP_LT:
3698f37c086134874a2ba372f6750a45466473a813b1dejanj               op = 12;
3699362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               break;
3700f37c086134874a2ba372f6750a45466473a813b1dejanj            case Mfp_CMP_NGT:
3701f37c086134874a2ba372f6750a45466473a813b1dejanj               op = 15;
3702f37c086134874a2ba372f6750a45466473a813b1dejanj               break;
3703362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            default:
3704362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               goto bad;
3705362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
3706f37c086134874a2ba372f6750a45466473a813b1dejanj         /* c.cond.d fr_srcL, fr_srcR
3707f37c086134874a2ba372f6750a45466473a813b1dejanj            cfc1     r_dst,   $31
3708f37c086134874a2ba372f6750a45466473a813b1dejanj            srl      r_dst,   r_dst, 23
3709f37c086134874a2ba372f6750a45466473a813b1dejanj            andi     r_dst,   r_dst, 1 */
3710f37c086134874a2ba372f6750a45466473a813b1dejanj         p = mkFormR(p, 0x11, 0x11, fr_srcL, fr_srcR, 0, op + 48);
3711f37c086134874a2ba372f6750a45466473a813b1dejanj         p = mkFormR(p, 0x11, 0x2, r_dst, 31, 0, 0);
3712f37c086134874a2ba372f6750a45466473a813b1dejanj         p = mkFormS(p, 0, r_dst, 0, r_dst, 23, 2);
3713f37c086134874a2ba372f6750a45466473a813b1dejanj         p = mkFormI(p, 12, r_dst, r_dst, 1);
3714362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
3715362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
3716b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
3717b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case Min_FpGpMove: {
3718b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         switch (i->Min.FpGpMove.op) {
3719b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            UInt rt, fs;
3720b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case MFpGpMove_mfc1: {
3721b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               rt = iregNo(i->Min.FpGpMove.dst, mode64);
3722b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               fs = fregNo(i->Min.FpGpMove.src, mode64);
3723b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               p = mkFormR(p, 0x11, 0x0, rt, fs, 0x0, 0x0);
3724b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               break;
3725b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            }
3726b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case MFpGpMove_dmfc1: {
3727b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               vassert(mode64);
3728b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               rt = iregNo(i->Min.FpGpMove.dst, mode64);
3729b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               fs = fregNo(i->Min.FpGpMove.src, mode64);
3730b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               p = mkFormR(p, 0x11, 0x1, rt, fs, 0x0, 0x0);
3731b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               break;
3732b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            }
3733b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case MFpGpMove_mtc1: {
3734b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               rt = iregNo(i->Min.FpGpMove.src, mode64);
3735b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               fs = fregNo(i->Min.FpGpMove.dst, mode64);
3736b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               p = mkFormR(p, 0x11, 0x4, rt, fs, 0x0, 0x0);
3737b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               break;
3738b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            }
3739b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case MFpGpMove_dmtc1: {
3740b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               vassert(mode64);
3741b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               rt = iregNo(i->Min.FpGpMove.src, mode64);
3742b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               fs = fregNo(i->Min.FpGpMove.dst, mode64);
3743b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               p = mkFormR(p, 0x11, 0x5, rt, fs, 0x0, 0x0);
3744b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               break;
3745b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            }
3746b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            default:
3747b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               goto bad;
3748b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         }
3749b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         goto done;
3750b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      }
3751b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
3752b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      case Min_MoveCond: {
3753b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         switch (i->Min.MoveCond.op) {
3754b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            UInt d, s, t;
3755b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case MFpMoveCond_movns: {
3756b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               d = fregNo(i->Min.MoveCond.dst, mode64);
3757b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               s = fregNo(i->Min.MoveCond.src, mode64);
3758b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               t = iregNo(i->Min.MoveCond.cond, mode64);
3759b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               p = mkFormR(p, 0x11, 0x10, t, s, d, 0x13);
3760b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               break;
3761b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            }
3762b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case MFpMoveCond_movnd: {
3763b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               d = dregNo(i->Min.MoveCond.dst);
3764b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               s = dregNo(i->Min.MoveCond.src);
3765b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               t = iregNo(i->Min.MoveCond.cond, mode64);
3766b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               p = mkFormR(p, 0x11, 0x11, t, s, d, 0x13);
3767b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               break;
3768b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            }
3769b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            case MMoveCond_movn: {
3770b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               d = iregNo(i->Min.MoveCond.dst, mode64);
3771b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               s = iregNo(i->Min.MoveCond.src, mode64);
3772b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               t = iregNo(i->Min.MoveCond.cond, mode64);
3773b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               p = mkFormR(p, 0, s, t, d, 0, 0xb);
3774b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               break;
3775b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            }
3776b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            default:
3777b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               goto bad;
3778b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         }
3779b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         goto done;
3780b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      }
3781b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
3782362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_EvCheck: {
3783362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* This requires a 32-bit dec/test in 32 mode. */
3784362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* We generate:
3785362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               lw      r9, amCounter
3786362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               addiu   r9, r9, -1
3787362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               sw      r9, amCounter
3788362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               bgez    r9, nofail
3789362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               lw      r9, amFailAddr
3790362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               jalr    r9
3791362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj               nop
3792362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj              nofail:
3793362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         */
3794362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         UChar* p0 = p;
3795362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* lw  r9, amCounter */
37960c30de83fbcb0f485c34c60f64e2994eaff37875petarj         p = do_load_or_store_word32(p, True /*isLoad*/ , /*r*/ 9,
3797362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                                     i->Min.EvCheck.amCounter, mode64);
3798362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* addiu r9,r9,-1 */
3799362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         p = mkFormI(p, 9, 9, 9, 0xFFFF);
3800362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* sw r30, amCounter */
38010c30de83fbcb0f485c34c60f64e2994eaff37875petarj         p = do_load_or_store_word32(p, False /*!isLoad*/ , /*r*/ 9,
3802362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                                     i->Min.EvCheck.amCounter, mode64);
3803362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* bgez t9, nofail */
3804362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         p = mkFormI(p, 1, 9, 1, 3);
38050c30de83fbcb0f485c34c60f64e2994eaff37875petarj         /* lw/ld r9, amFailAddr */
3806b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         p = do_load_or_store_machine_word(p, True /*isLoad*/ , /*r*/ 9,
3807362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                                           i->Min.EvCheck.amFailAddr, mode64);
3808362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* jalr $9 */
3809b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         p = mkFormR(p, 0, 9, 0, 31, 0, 9);  /* p += 4 */
3810b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj         p = mkFormR(p, 0, 0, 0, 0, 0, 0);   /* p += 4 */
3811362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* nofail: */
3812b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
3813362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* Crosscheck */
38147ce2cc883c5b36586babec833838951ecf9f2a76florian         vassert(evCheckSzB_MIPS() == (UChar*)p - (UChar*)p0);
3815362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
3816362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
3817362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3818362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      case Min_ProfInc: {
3819362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* Generate a code template to increment a memory location whose
3820362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            address will be known later as an immediate value. This code
3821362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            template will be patched once the memory location is known.
3822b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            For now we do this with address == 0x65556555. */
3823362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         if (mode64) {
3824b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            /* 64-bit:
3825b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               move r9, 0x6555655565556555ULL
3826b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               ld r8, 0(r9)
3827b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               daddiu r8, r8, 1
3828b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               sd r8, 0(r9) */
3829b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
3830b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            /* move r9, 0x6555655565556555ULL */
3831b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            p = mkLoadImm_EXACTLY2or6(p, /*r*/ 9, 0x6555655565556555ULL,
3832b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                                      True /*mode64*/);
3833b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            /* ld r8, 0(r9) */
3834b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            p = mkFormI(p, 55, 9, 8, 0);
3835b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
3836b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            /* daddiu r8, r8, 1 */
3837b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            p = mkFormI(p, 25, 8, 8, 1);
3838b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
3839b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            /* sd r8, 0(r9) */
3840b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            p = mkFormI(p, 63, 9, 8, 0);
3841362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         } else {
3842b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            /* 32-bit:
3843b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               move r9, 0x65556555
3844b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               lw r8, 0(r9)
3845b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               addiu r8, r8, 1         # add least significant word
3846b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               sw r8, 0(r9)
3847b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               sltiu r1, r8, 1         # set carry-in bit
3848b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               lw r8, 4(r9)
3849b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               addu r8, r8, r1
3850b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj               sw r8, 4(r9) */
3851b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
3852b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            /* move r9, 0x65556555 */
3853b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            p = mkLoadImm_EXACTLY2or6(p, /*r*/ 9, 0x65556555ULL,
3854b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                                      False /*!mode64*/);
3855b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            /* lw r8, 0(r9) */
3856362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            p = mkFormI(p, 35, 9, 8, 0);
3857362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3858b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            /* addiu r8, r8, 1         # add least significant word */
3859362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            p = mkFormI(p, 9, 8, 8, 1);
3860362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3861b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            /* sw r8, 0(r9) */
3862362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            p = mkFormI(p, 43, 9, 8, 0);
3863362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3864b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            /* sltiu r1, r8, 1         # set carry-in bit */
3865362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            p = mkFormI(p, 11, 8, 1, 1);
3866362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3867b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            /* lw r8, 4(r9) */
3868362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            p = mkFormI(p, 35, 9, 8, 4);
3869362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3870b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            /* addu r8, r8, r1 */
3871362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            p = mkFormR(p, 0, 8, 1, 8, 0, 33);
3872362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3873b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj            /*  sw r8, 4(r9) */
3874362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj            p = mkFormI(p, 43, 9, 8, 4);
3875362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3876362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         }
3877362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         /* Tell the caller .. */
3878362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         vassert(!(*is_profInc));
3879362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         *is_profInc = True;
3880362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto done;
3881362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      }
3882b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj
3883362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      default:
3884362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj         goto bad;
3885362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3886362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   }
3887362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3888362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   bad:
3889362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      vex_printf("\n=> ");
3890362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      ppMIPSInstr(i, mode64);
3891362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      vpanic("emit_MIPSInstr");
3892b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      /* NOTREACHED */ done:
3893b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      vassert(p - &buf[0] <= 128);
3894362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      return p - &buf[0];
3895362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
3896362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3897362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* How big is an event check?  See case for Min_EvCheck in
3898362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   emit_MIPSInstr just above.  That crosschecks what this returns, so
3899362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   we can tell if we're inconsistent. */
39007ce2cc883c5b36586babec833838951ecf9f2a76florianInt evCheckSzB_MIPS (void)
3901362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
3902362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj  UInt kInstrSize = 4;
3903362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj  return 7*kInstrSize;
3904362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
3905362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3906362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* NB: what goes on here has to be very closely coordinated with the
3907362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   emitInstr case for XDirect, above. */
39089b76916dcc1628e133d57db001563429c6e3a590sewardjVexInvalRange chainXDirect_MIPS ( VexEndness endness_host,
39099b76916dcc1628e133d57db001563429c6e3a590sewardj                                  void* place_to_chain,
39107d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                  const void* disp_cp_chain_me_EXPECTED,
39117d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                  const void* place_to_jump_to,
3912362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                                  Bool  mode64 )
3913362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
39149b76916dcc1628e133d57db001563429c6e3a590sewardj   vassert(endness_host == VexEndnessLE || endness_host == VexEndnessBE);
3915362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   /* What we're expecting to see is:
3916362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj        move r9, disp_cp_chain_me_to_EXPECTED
3917362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj        jalr r9
3918362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj        nop
3919362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      viz
3920b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj        <8 or 24 bytes generated by mkLoadImm_EXACTLY2or6>
3921b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj        0x120F809   # jalr r9
3922b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj        0x00000000  # nop
3923362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   */
3924362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   UChar* p = (UChar*)place_to_chain;
3925362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(0 == (3 & (HWord)p));
3926b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   vassert(isLoadImm_EXACTLY2or6(p, /*r*/9,
392793a09742b0de3d61718882c2d999f64be402564dflorian                                 (UInt)(Addr)disp_cp_chain_me_EXPECTED,
3928362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                                 mode64));
3929b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   vassert(fetch32(p + (mode64 ? 24 : 8) + 0) == 0x120F809);
3930b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   vassert(fetch32(p + (mode64 ? 24 : 8) + 4) == 0x00000000);
3931362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   /* And what we want to change it to is either:
3932362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj          move r9, place_to_jump_to
3933362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj          jalr r9
3934362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj          nop
3935362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj        viz
3936b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj          <8 bytes generated by mkLoadImm_EXACTLY2or6>
3937b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj          0x120F809   # jalr r9
3938b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj          0x00000000  # nop
3939362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3940362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      The replacement has the same length as the original.
3941362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   */
3942362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3943b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   p = mkLoadImm_EXACTLY2or6(p, /*r*/9,
394493a09742b0de3d61718882c2d999f64be402564dflorian                             (Addr)place_to_jump_to, mode64);
3945362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   p = emit32(p, 0x120F809);
3946362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   p = emit32(p, 0x00000000);
3947362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3948362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   Int len = p - (UChar*)place_to_chain;
3949b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   vassert(len == (mode64 ? 32 : 16)); /* stay sane */
3950362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   VexInvalRange vir = {(HWord)place_to_chain, len};
3951362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return vir;
3952362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
3953362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3954362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* NB: what goes on here has to be very closely coordinated with the
3955362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   emitInstr case for XDirect, above. */
39569b76916dcc1628e133d57db001563429c6e3a590sewardjVexInvalRange unchainXDirect_MIPS ( VexEndness endness_host,
39579b76916dcc1628e133d57db001563429c6e3a590sewardj                                    void* place_to_unchain,
39587d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                    const void* place_to_jump_to_EXPECTED,
39597d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                    const void* disp_cp_chain_me,
3960362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                                    Bool  mode64 )
3961362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
39629b76916dcc1628e133d57db001563429c6e3a590sewardj   vassert(endness_host == VexEndnessLE || endness_host == VexEndnessBE);
3963362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   /* What we're expecting to see is:
3964362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj        move r9, place_to_jump_to_EXPECTED
3965362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj        jalr r9
3966362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj        nop
3967362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      viz
3968b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj        <8 or 24 bytes generated by mkLoadImm_EXACTLY2or6>
3969b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj        0x120F809   # jalr r9
3970b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj        0x00000000  # nop
3971362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   */
3972362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   UChar* p = (UChar*)place_to_unchain;
3973362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(0 == (3 & (HWord)p));
3974b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   vassert(isLoadImm_EXACTLY2or6(p, /*r*/ 9,
397593a09742b0de3d61718882c2d999f64be402564dflorian                                 (Addr)place_to_jump_to_EXPECTED,
3976362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj                                 mode64));
3977b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   vassert(fetch32(p + (mode64 ? 24 : 8) + 0) == 0x120F809);
3978b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   vassert(fetch32(p + (mode64 ? 24 : 8) + 4) == 0x00000000);
3979362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   /* And what we want to change it to is:
3980362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj        move r9, disp_cp_chain_me
3981362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj        jalr r9
3982362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj        nop
3983362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      viz
3984b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj        <8 or 24 bytes generated by mkLoadImm_EXACTLY2or6>
3985b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj        0x120F809   # jalr r9
3986b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj        0x00000000  # nop
3987362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj      The replacement has the same length as the original.
3988362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   */
3989b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   p = mkLoadImm_EXACTLY2or6(p, /*r*/ 9,
399093a09742b0de3d61718882c2d999f64be402564dflorian                             (Addr)disp_cp_chain_me, mode64);
3991362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   p = emit32(p, 0x120F809);
3992362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   p = emit32(p, 0x00000000);
3993362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
3994362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   Int len = p - (UChar*)place_to_unchain;
3995b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   vassert(len == (mode64 ? 32 : 16)); /* stay sane */
3996362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   VexInvalRange vir = {(HWord)place_to_unchain, len};
3997362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return vir;
3998362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
3999362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
4000362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/* Patch the counter address into a profile inc point, as previously
4001362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   created by the Min_ProfInc case for emit_MIPSInstr. */
40029b76916dcc1628e133d57db001563429c6e3a590sewardjVexInvalRange patchProfInc_MIPS ( VexEndness endness_host,
40039b76916dcc1628e133d57db001563429c6e3a590sewardj                                  void*  place_to_patch,
40047d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                  const ULong* location_of_counter,
40057d6f81de12e6d8deb3e119ab318f361d97a10a65florian                                  Bool mode64 )
4006362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj{
40079b76916dcc1628e133d57db001563429c6e3a590sewardj   vassert(endness_host == VexEndnessLE || endness_host == VexEndnessBE);
40089b76916dcc1628e133d57db001563429c6e3a590sewardj   if (mode64) {
4009b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      vassert(sizeof(ULong*) == 8);
40109b76916dcc1628e133d57db001563429c6e3a590sewardj   } else {
4011b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      vassert(sizeof(ULong*) == 4);
40129b76916dcc1628e133d57db001563429c6e3a590sewardj   }
4013362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   UChar* p = (UChar*)place_to_patch;
4014362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   vassert(0 == (3 & (HWord)p));
4015b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   vassert(isLoadImm_EXACTLY2or6((UChar *)p, /*r*/9,
4016b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                                 mode64 ? 0x6555655565556555ULL : 0x65556555,
4017b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj                                 mode64));
4018362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
4019b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   if (mode64) {
4020b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      vassert(fetch32(p + 24 + 0) == 0xDD280000);
4021b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      vassert(fetch32(p + 24 + 4) == 0x65080001);
4022b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      vassert(fetch32(p + 24 + 8) == 0xFD280000);
4023b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   } else {
4024b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      vassert(fetch32(p + 8 + 0) == 0x8D280000);
4025b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      vassert(fetch32(p + 8 + 4) == 0x25080001);
4026b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      vassert(fetch32(p + 8 + 8) == 0xAD280000);
4027b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      vassert(fetch32(p + 8 + 12) == 0x2d010001);
4028b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      vassert(fetch32(p + 8 + 16) == 0x8d280004);
4029b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      vassert(fetch32(p + 8 + 20) == 0x01014021);
4030b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj      vassert(fetch32(p + 8 + 24) == 0xad280004);
4031b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   }
4032362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
4033b92a95406aca7bba15ecc9b5828a16fdbbdc8778petarj   p = mkLoadImm_EXACTLY2or6(p, /*r*/9,
403493a09742b0de3d61718882c2d999f64be402564dflorian                             (Addr)location_of_counter, mode64);
4035362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
4036362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   VexInvalRange vir = {(HWord)p, 8};
4037362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj   return vir;
4038362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj}
4039362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
4040362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj
4041362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/*---------------------------------------------------------------*/
4042362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/*--- end                                    host_mips_defs.c ---*/
4043362cf841bd241b9eb32e63bcab8b1f0042caa6f0sewardj/*---------------------------------------------------------------*/
4044