* amd64-linux-nat.c (compat_int_t, compat_uptr_t, compat_time_t)
[binutils-gdb.git] / sim / mips / vr.igen
blob9266ae6dc613865427e17cfa2060242fb26fed62
1 // -*- C -*-
2 //
3 // NEC specific instructions
4 //
6 :%s::::MFHI:int hi
8   return hi ? "hi" : "";
11 :%s::::SAT:int s
13   return s ? "s" : "";
16 :%s::::UNS:int u
18   return u ? "u" : "";
21 // Simulate the various kinds of multiply and multiply-accumulate instructions.
22 // Perform an operation of the form:
24 //      LHS (+/-) GPR[RS] * GPR[RT]
26 // and store it in the 64-bit accumulator.  Optionally copy either LO or
27 // HI into a general purpose register.
29 // - RD is the destination register of the LO or HI move
30 // - RS are RT are the multiplication source registers
31 // - ACCUMULATE_P is true if LHS should be the value of the 64-bit accumulator,
32 //     false if it should be 0.
33 // - STORE_HI_P is true if HI should be stored in RD, false if LO should be.
34 // - UNSIGNED_P is true if the operation should be unsigned.
35 // - SATURATE_P is true if the result should be saturated to a 32-bit value.
36 // - SUBTRACT_P is true if the right hand side should be subtraced from LHS,
37 //     false if it should be added.
38 // - SHORT_P is true if RS and RT must be 16-bit numbers.
39 // - DOUBLE_P is true if the 64-bit accumulator is in LO, false it is a
40 //     concatenation of the low 32 bits of HI and LO.
41 :function:::void:do_vr_mul_op:int rd, int rs, int rt, int accumulate_p, int store_hi_p, int unsigned_p, int saturate_p, int subtract_p, int short_p, int double_p
43   unsigned64 lhs, x, y, xcut, ycut, product, result;
45   check_mult_hilo (SD_, HIHISTORY, LOHISTORY);
47   lhs = (!accumulate_p ? 0 : double_p ? LO : U8_4 (HI, LO));
48   x = GPR[rs];
49   y = GPR[rt];
51   /* Work out the canonical form of X and Y from their significant bits.  */
52   if (!short_p)
53     {
54       /* Normal sign-extension rule for 32-bit operands.  */
55       xcut = EXTEND32 (x);
56       ycut = EXTEND32 (y);
57     }
58   else if (unsigned_p)
59     {
60       /* Operands must be zero-extended 16-bit numbers.  */
61       xcut = x & 0xffff;
62       ycut = y & 0xffff;
63     }
64   else
65     {
66       /* Likewise but sign-extended.  */
67       xcut = EXTEND16 (x);
68       ycut = EXTEND16 (y);
69     }
70   if (x != xcut || y != ycut)
71     sim_engine_abort (SD, CPU, CIA,
72                       "invalid multiplication operand at 0x%08lx\n",
73                       (long) CIA);
75   TRACE_ALU_INPUT2 (x, y);
76   product = (unsigned_p
77              ? V8_4 (x, 1) * V8_4 (y, 1)
78              : EXTEND32 (x) * EXTEND32 (y));
79   result = (subtract_p ? lhs - product : lhs + product);
80   if (saturate_p)
81     {
82       /* Saturate the result to 32 bits.  An unsigned, unsaturated
83          result is zero-extended to 64 bits, but unsigned overflow
84          causes all 64 bits to be set.  */
85       if (!unsigned_p && (unsigned64) EXTEND32 (result) != result)
86         result = ((signed64) result < 0 ? -0x7fffffff - 1 : 0x7fffffff);
87       else if (unsigned_p && (result >> 32) != 0)
88         result = (unsigned64) 0 - 1;
89     }
90   TRACE_ALU_RESULT (result);
92   if (double_p)
93     LO = result;
94   else
95     {
96       LO = EXTEND32 (result);
97       HI = EXTEND32 (VH4_8 (result));
98     }
99   if (rd != 0)
100     GPR[rd] = store_hi_p ? HI : LO;
103 // VR4100 instructions.
105 000000,5.RS,5.RT,00000,00000,101000::32::MADD16
106 "madd16 r<RS>, r<RT>"
107 *vr4100:
109   do_vr_mul_op (SD_, 0, RS, RT,
110                 1 /* accumulate */,
111                 0 /* store in LO */,
112                 0 /* signed arithmetic */,
113                 0 /* don't saturate */,
114                 0 /* don't subtract */,
115                 1 /* short */,
116                 0 /* single */);
119 000000,5.RS,5.RT,00000,00000,101001::64::DMADD16
120 "dmadd16 r<RS>, r<RT>"
121 *vr4100:
123   do_vr_mul_op (SD_, 0, RS, RT,
124                 1 /* accumulate */,
125                 0 /* store in LO */,
126                 0 /* signed arithmetic */,
127                 0 /* don't saturate */,
128                 0 /* don't subtract */,
129                 1 /* short */,
130                 1 /* double */);
135 // VR4120 and VR4130 instructions.
137 000000,5.RS,5.RT,5.RD,1.SAT,1.MFHI,00,1.UNS,101001::64::DMACC
138 "dmacc%s<MFHI>%s<UNS>%s<SAT> r<RD>, r<RS>, r<RT>"
139 *vr4120:
141   do_vr_mul_op (SD_, RD, RS, RT,
142                 1 /* accumulate */,
143                 MFHI, UNS, SAT,
144                 0 /* don't subtract */,
145                 SAT /* short */,
146                 1 /* double */);
149 000000,5.RS,5.RT,5.RD,1.SAT,1.MFHI,00,1.UNS,101000::32::MACC_4120
150 "macc%s<MFHI>%s<UNS>%s<SAT> r<RD>, r<RS>, r<RT>"
151 *vr4120:
153   do_vr_mul_op (SD_, RD, RS, RT,
154                 1 /* accumulate */,
155                 MFHI, UNS, SAT,
156                 0 /* don't subtract */,
157                 SAT /* short */,
158                 0 /* single */);
162 // VR5400 and VR5500 instructions.
164 000000,5.RS,5.RT,5.RD,0,1.MFHI,001,01100,1.UNS::32::MUL
165 "mul%s<MFHI>%s<UNS> r<RD>, r<RS>, r<RT>"
166 *vr5400:
167 *vr5500:
169   do_vr_mul_op (SD_, RD, RS, RT,
170                 0 /* don't accumulate */,
171                 MFHI, UNS,
172                 0 /* don't saturate */,
173                 0 /* don't subtract */,
174                 0 /* not short */,
175                 0 /* single */);
178 000000,5.RS,5.RT,5.RD,0,1.MFHI,011,01100,1.UNS::32::MULS
179 "muls%s<MFHI>%s<UNS> r<RD>, r<RS>, r<RT>"
180 *vr5400:
181 *vr5500:
183   do_vr_mul_op (SD_, RD, RS, RT,
184                 0 /* don't accumulate */,
185                 MFHI, UNS,
186                 0 /* don't saturate */,
187                 1 /* subtract */,
188                 0 /* not short */,
189                 0 /* single */);
192 000000,5.RS,5.RT,5.RD,0,1.MFHI,101,01100,1.UNS::32::MACC_5xxx
193 "macc%s<MFHI>%s<UNS> r<RD>, r<RS>, r<RT>"
194 *vr5400:
195 *vr5500:
197   do_vr_mul_op (SD_, RD, RS, RT,
198                 1 /* accumulate */,
199                 MFHI, UNS,
200                 0 /* don't saturate */,
201                 0 /* don't subtract */,
202                 0 /* not short */,
203                 0 /* single */);
206 000000,5.RS,5.RT,5.RD,0,1.MFHI,111,01100,1.UNS::32::MSAC
207 "msac%s<MFHI>%s<UNS> r<RD>, r<RS>, r<RT>"
208 *vr5400:
209 *vr5500:
211   do_vr_mul_op (SD_, RD, RS, RT,
212                 1 /* accumulate */,
213                 MFHI, UNS,
214                 0 /* don't saturate */,
215                 1 /* subtract */,
216                 0 /* not short */,
217                 0 /* single */);
221 010011,5.BASE,5.INDEX,5.0,5.FD,000101:COP1X:64::LUXC1
222 "luxc1 f<FD>, r<INDEX>(r<BASE>)"
223 *vr5500:
225   check_fpu (SD_);
226   COP_LD (1, FD, do_load (SD_, AccessLength_DOUBLEWORD,
227                           (GPR[BASE] + GPR[INDEX]) & ~MASK64 (2, 0), 0));
230 010011,5.BASE,5.INDEX,5.FS,00000,001101:COP1X:64::SUXC1
231 "suxc1 f<FS>, r<INDEX>(r<BASE>)"
232 *vr5500:
234   check_fpu (SD_);
235   do_store (SD_, AccessLength_DOUBLEWORD,
236             (GPR[BASE] + GPR[INDEX]) & ~MASK64 (2, 0), 0,
237             COP_SD (1, FS));
240 010000,1,19.*,100000:COP0:32::WAIT
241 "wait"
242 *vr5500:
244 011100,00000,5.RT,5.DR,00000,111101:SPECIAL:64::MFDR
245 "mfdr r<RT>, r<DR>"
246 *vr5400:
247 *vr5500:
249 011100,00100,5.RT,5.DR,00000,111101:SPECIAL:64::MTDR
250 "mtdr r<RT>, r<DR>"
251 *vr5400:
252 *vr5500:
254 011100,00000,00000,00000,00000,111110:SPECIAL:64::DRET
255 "dret"
256 *vr5400:
257 *vr5500: