1110010,26.OFFSET:POOL32X:32::BC
2"bc <OFFSET>"
3*mips32r6:
4*mips64r6:
5{
6  NIA = CIA + (EXTEND26 (OFFSET) << 2) + 4;
7}
8
9111010,26.OFFSET:POOL32X:32::BALC
10"balc <OFFSET>"
11*mips32r6:
12*mips64r6:
13{
14  RA = CIA + 4;
15  NIA = CIA + (EXTEND26 (OFFSET) << 2) + 4;
16}
17
18110110,5.RS!0,21.OFFSET:POOL32X:32::BEQZC
19"beqzc r<RS>, <OFFSET>"
20*mips32r6:
21*mips64r6:
22{
23  if (GPR[RS] == 0)
24    NIA = CIA + (EXTEND21 (OFFSET) << 2) + 4;
25  else
26    FORBIDDEN_SLOT ();
27}
28
29110110,00000,5.RT,16.OFFSET:POOL32X:32::JIC
30"jic r<RT>, <OFFSET>"
31*mips32r6:
32*mips64r6:
33{
34  NIA = GPR[RT] + (EXTEND16(OFFSET) << 2);
35}
36
37111110,5.RS!0,21.OFFSET:POOL32X:32::BNEZC
38"bnezc r<RS>, <OFFSET>"
39*mips32r6:
40*mips64r6:
41{
42  if (GPR[RS] != 0)
43    NIA = CIA + (EXTEND21 (OFFSET) << 2) + 4;
44  else
45    FORBIDDEN_SLOT ();
46}
47
48111110,00000,5.RT,16.OFFSET:POOL32X:32::JIALC
49"jialc r<RT>, <OFFSET>"
50*mips32r6:
51*mips64r6:
52{
53  RA = CIA + 4;
54  NIA = GPR[RT] + EXTEND16(OFFSET);
55}
56
57010110,5.RS,5.RT,16.OFFSET:POOL32X:32::B1xxC
58"blezc r<RT>, <OFFSET>": RS==0&&RT!=0
59"bgezc r<RT>, <OFFSET>":RS!=0&&RS==RT
60"bgec r<RS>, r<RT>, <OFFSET>"
61*mips32r6:
62*mips64r6:
63{
64  if (RS == 0 && RT != 0)
65    {
66      //BLEZC
67      if ((signed_word)GPR[RT] <= 0)
68	NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
69      else
70	FORBIDDEN_SLOT ();
71    }
72  else if (RS != 0 && RS == RT)
73    {
74      //BGEZC
75      if ((signed_word)GPR[RT] >= 0)
76	NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
77      else
78	FORBIDDEN_SLOT ();
79    }
80  else
81    {
82      //BGEC
83      if ((signed_word) GPR[RS] >= (signed_word) GPR[RT])
84	NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
85      else
86	FORBIDDEN_SLOT ();
87    }
88}
89
90010111,5.RS,5.RT,16.OFFSET:POOL32X:32::B2xxC
91"bgtzc r<RT>, <OFFSET>":RS==0&&RT!=0
92"bltzc r<RT>, <OFFSET>":RS!=0&&RS==RT
93"bltc r<RS>, r<RT>, <OFFSET>"
94*mips32r6:
95*mips64r6:
96{
97  if (RS == 0 && RT != 0)
98    {
99      //BGTZC
100      if ((signed_word)GPR[RT] > 0)
101	NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
102      else
103	FORBIDDEN_SLOT ();
104    }
105  else if (RS != 0 && RS == RT)
106    {
107      //BLTZC
108      if ((signed_word)GPR[RT] < 0)
109	NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
110      else
111	FORBIDDEN_SLOT ();
112    }
113  else
114    {
115      //BLTC
116      if ((signed_word) GPR[RS] < (signed_word) GPR[RT])
117	NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
118      else
119	FORBIDDEN_SLOT ();
120    }
121}
122
123000110,5.RS,5.RT!0,16.OFFSET:POOL32X:32::B3xxC
124"blezalc r<RT>, <OFFSET>":RS==0
125"bgezalc r<RT>, <OFFSET>":RS!=0&&RS==RT
126"bgeuc r<RS>, r<RT>, <OFFSET>"
127*mips32r6:
128*mips64r6:
129{
130  if (RS == 0 && RT != 0)
131    {
132      //BLEZALC
133      RA = CIA + 4;
134      if ((signed_word)GPR[RT] <= 0)
135	NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
136      else
137	FORBIDDEN_SLOT ();
138    }
139  else if (RS != 0 && RS == RT)
140    {
141      //BGEZALC
142      RA = CIA + 4;
143      if ((signed_word)GPR[RT] >= 0)
144	NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
145      else
146	FORBIDDEN_SLOT ();
147    }
148  else
149    {
150      //BGEUC
151      if (GPR[RS] >= GPR[RT])
152	NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
153      else
154	FORBIDDEN_SLOT ();
155    }
156}
157
158000111,5.RS,5.RT!0,16.OFFSET:POOL32X:32::B4xxC
159"bgtzalc r<RT>, <OFFSET>":RS==0
160"bltzalc r<RT>, <OFFSET>":RS!=0&&RS==RT
161"bltuc r<RS>, r<RT>, <OFFSET>"
162*mips32r6:
163*mips64r6:
164{
165  if (RS == 0 && RT != 0)
166    {
167      //BGTZALC
168      RA = CIA + 4;
169      if ((signed_word)GPR[RT] > 0)
170	NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
171      else
172	FORBIDDEN_SLOT ();
173    }
174  else if (RS != 0 && RS == RT)
175    {
176      //BLTZALC
177      RA = CIA + 4;
178      if ((signed_word)GPR[RT] < 0)
179	NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
180      else
181	FORBIDDEN_SLOT ();
182    }
183  else
184    {
185      //BLTUC
186      if (GPR[RS] < GPR[RT])
187	NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
188      else
189	FORBIDDEN_SLOT ();
190    }
191}
192
193001000,5.RS,5.RT,16.OFFSET:POOL32X:32::BxxxC
194"bovc r<RS>, r<RT>, <OFFSET>":RS>=RT
195"beqzalc r<RT>, <OFFSET>":RS==0&&RT>RS
196"beqc r<RS>, r<RT>, <OFFSET>"
197*mips32r6:
198*mips64r6:
199{
200  if (RS >= RT)
201    {
202      //BOVC
203      ALU32_BEGIN (GPR[RS] & 0x0ffffffff);
204      ALU32_ADD (GPR[RT] & 0x0ffffffff);
205
206      if (ALU32_HAD_OVERFLOW)
207	NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
208      else
209	FORBIDDEN_SLOT ();
210    }
211  else if (RS == 0)
212    {
213      RA = CIA + 4;
214      //BEQZALC
215      if (GPR[RT] == 0)
216	NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
217      else
218	FORBIDDEN_SLOT ();
219    }
220  else
221    {
222      //BEQC
223      if (GPR[RS] == GPR[RT])
224	NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
225      else
226	FORBIDDEN_SLOT ();
227    }
228}
229
230011000,5.RS,5.RT,16.OFFSET:POOL32X:32::BNxxxC
231"bnvc r<RS>, r<RT>, <OFFSET>":RS>=RT
232"bnezalc r<RT>, <OFFSET>":RS==0&&RT>RS
233"bnec r<RS>, r<RT>, <OFFSET>"
234*mips32r6:
235*mips64r6:
236{
237  if (RS >= RT)
238    {
239      //BNVC
240      ALU32_BEGIN (GPR[RS] & 0x0ffffffff);
241      ALU32_ADD (GPR[RT] & 0x0ffffffff);
242
243      if (!ALU32_HAD_OVERFLOW)
244	NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
245      else
246	FORBIDDEN_SLOT ();
247    }
248  else if (RS == 0 && RT > RS)
249    {
250      //BNEZALC
251      RA = CIA + 4;
252      if (GPR[RT] != 0)
253	NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
254      else
255	FORBIDDEN_SLOT ();
256    }
257  else
258    {
259      //BNEC
260      if (GPR[RT] != GPR[RS])
261	NIA = CIA + (EXTEND16 (OFFSET) << 2) + 4;
262      else
263	FORBIDDEN_SLOT ();
264    }
265}
266
267:%s::::R6COND:int r6cond
268{
269  switch (r6cond)
270    {
271    case FP_R6CMP_SAF:
272      return "SAF";
273    case FP_R6CMP_SUN:
274      return "SUN";
275    case FP_R6CMP_SOR:
276      return "SOR";
277    case FP_R6CMP_SEQ:
278      return "SEQ";
279    case FP_R6CMP_SUNE:
280      return "SUNE";
281    case FP_R6CMP_SUEQ:
282      return "SUEQ";
283    case FP_R6CMP_SNE:
284      return "SNE";
285    case FP_R6CMP_SLT:
286      return "SLT";
287    case FP_R6CMP_SULT:
288      return "SULT";
289    case FP_R6CMP_SLE:
290      return "SLE";
291    case FP_R6CMP_SULE:
292      return "SULE";
293    case FP_R6CMP_AF:
294      return "AF";
295    case FP_R6CMP_UN:
296      return "UN";
297    case FP_R6CMP_OR:
298      return "OR";
299    case FP_R6CMP_EQ:
300      return "EQ";
301    case FP_R6CMP_UNE:
302      return "UNE";
303    case FP_R6CMP_UEQ:
304      return "UEQ";
305    case FP_R6CMP_NE:
306      return "NE";
307    case FP_R6CMP_LT:
308      return "LT";
309    case FP_R6CMP_ULT:
310      return "ULT";
311    case FP_R6CMP_LE:
312      return "LE";
313    case FP_R6CMP_ULE:
314      return "ULE";
315    default:
316      abort ();
317    }
318}
319
320010001,1010,1.FMT,5.FT,5.FS,5.FD,0,5.R6COND:POOL32X:32,f::CMP.cond.fmt
321"cmp.%s<R6COND>.%s<FMT> f<FD>, f<FS>, f<FT>"
322*mips32r6:
323*mips64r6:
324{
325  uint64_t result;
326  check_fpu (SD_);
327  TRACE_ALU_INPUT2 (ValueFPR (FS, FMT), ValueFPR (FT, FMT));
328
329  result = R6Compare (ValueFPR (FS, FMT), ValueFPR (FT, FMT), FMT, R6COND);
330  StoreFPR (FD, FMT, result);
331  TRACE_ALU_RESULT (result);
332}
333
334010001,01001,5.FT,16.OFFSET:POOL32X:32,f::BC1EQZ
335"bc1eqz f<FT>, <OFFSET>"
336*mips32r6:
337*mips64r6:
338{
339  address_word offset = EXTEND16 (OFFSET) << 2;
340  check_fpu (SD_);
341  TRACE_ALU_INPUT1 (FGR[FT]);
342  if ((FGR[FT] & 0x01) == 0)
343    DELAY_SLOT (NIA + offset);
344}
345
346010001,01101,5.FT,16.OFFSET:POOL32X:32,f::BC1NEZ
347"bc1nez f<FT>, <OFFSET>"
348*mips32r6:
349*mips64r6:
350{
351  address_word offset = EXTEND16 (OFFSET) << 2;
352  check_fpu (SD_);
353  TRACE_ALU_INPUT1 (FGR[FT]);
354  if ((FGR[FT] & 0x01) != 0)
355    DELAY_SLOT (NIA + offset);
356}
357010001,1000,1.FMT,5.FT,5.FS,5.FD,011000:POOLX:32,f::MADDF.fmt
358"maddf.%s<FMT> f<FD>, f<FS>, f<FT>"
359*mips32r6:
360*mips64r6:
361{
362  int fmt = FMT;
363  check_fpu (SD_);
364  check_u64 (SD_, instruction_0);
365  check_fmt_p (SD_, fmt, instruction_0);
366  TRACE_ALU_INPUT3 (FGR[FD], FGR[FS], FGR[FT]);
367  StoreFPR (FD, fmt, FusedMultiplyAdd (ValueFPR (FS, fmt),
368				       ValueFPR (FT, fmt),
369				       ValueFPR (FD, fmt), fmt));
370  TRACE_ALU_RESULT (FGR[FD]);
371}
372
373010001,1000,1.FMT,5.FT,5.FS,5.FD,011001:POOLX:32,f::MSUBF.fmt
374"msubf.%s<FMT> f<FD>, f<FS>, f<FT>"
375*mips32r6:
376*mips64r6:
377{
378  int fmt = FMT;
379  check_fpu (SD_);
380  check_u64 (SD_, instruction_0);
381  check_fmt_p (SD_, fmt, instruction_0);
382  TRACE_ALU_INPUT3 (FGR[FD], FGR[FS], FGR[FT]);
383  StoreFPR (FD, fmt, FusedMultiplySub (ValueFPR (FS, fmt),
384				       ValueFPR (FT, fmt),
385				       ValueFPR (FD, fmt), fmt));
386  TRACE_ALU_RESULT (FGR[FD]);
387}
388
389000000,5.RS,5.RT,5.RD,000,2.IMM,000101:SPECIAL:32::LSA
390"lsa r<RD>, r<RS>, r<RT>, <IMM + 1>"
391*mips32r6:
392*mips64r6:
393{
394  uint32_t t = GPR[RS] << (IMM + 1);
395  GPR[RD] = EXTEND32(GPR[RT] + t);
396  TRACE_ALU_RESULT (GPR[RD]);
397}
398
399000000,5.RS,5.RT,5.RD,000,2.IMM,010101:SPECIAL:64::DLSA
400"dlsa r<RD>, r<RS>, r<RT>, <IMM + 1>"
401*mips64r6:
402{
403  uint64_t t = GPR[RS] << (IMM + 1);
404  GPR[RD] = GPR[RT] + t;
405  TRACE_ALU_RESULT (GPR[RD]);
406}
407
408001111,5.RS!0,5.RT,16.IMMEDIATE:POOL32X:32::AUI
409"aui r<RS>, r<RT>, <IMMEDIATE>"
410*mips32r6:
411*mips64r6:
412{
413  TRACE_ALU_INPUT2 (GPR[RS], IMMEDIATE);
414  GPR[RT] = EXTEND32 (GPR[RS] + (EXTEND16 (IMMEDIATE) << 16));
415  TRACE_ALU_RESULT (GPR[RT]);
416}
417
418011101,5.RS!0,5.RT,16.IMMEDIATE:POOL32X:64::DAUI
419"daui r<RS>, r<RT>, <IMMEDIATE>"
420*mips64r6:
421{
422  TRACE_ALU_INPUT2 (GPR[RS], IMMEDIATE);
423  GPR[RT] = GPR[RS] + (EXTEND16 (IMMEDIATE) << 16);
424  TRACE_ALU_RESULT (GPR[RT]);
425}
426
427000001,5.RS,00110,16.IMMEDIATE:POOL32X:64::DAHI
428"dahi r<RS>, <IMMEDIATE>"
429*mips64r6:
430{
431  TRACE_ALU_INPUT2 (GPR[RS], IMMEDIATE);
432  GPR[RS] = GPR[RS] + (EXTEND16 (IMMEDIATE) << 32);
433  TRACE_ALU_RESULT (GPR[RS]);
434}
435
436000001,5.RS,11110,16.IMMEDIATE:POOL32X:64::DATI
437"dati r<RS>, <IMMEDIATE>"
438*mips64r6:
439{
440  TRACE_ALU_INPUT2 (GPR[RS], IMMEDIATE);
441  GPR[RS] = GPR[RS] + (EXTEND16 (IMMEDIATE) << 48);
442  TRACE_ALU_RESULT (GPR[RS]);
443}
444
445011111,5.RS,5.RT,5.RD,010,2.IMMEDIATE,100000:POOL32X:32::ALIGN
446"align r<RD>, r<RS>, r<RT>, <IMMEDIATE>"
447*mips32r6:
448*mips64r6:
449{
450  uint32_t rs = GPR[RS];
451  uint32_t rt = GPR[RT];
452  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
453  GPR[RD] = EXTEND32 (rs >> 8 * (4 - IMMEDIATE) | rt << 8 * IMMEDIATE);
454  TRACE_ALU_RESULT (GPR[RD]);
455}
456
457011111,5.RS,5.RT,5.RD,01,3.IMMEDIATE,100100:POOL32X:64::DALIGN
458"dalign r<RD>, r<RS>, r<RT>, <IMMEDIATE>"
459*mips64r6:
460{
461  uint64_t rs = GPR[RS];
462  uint64_t rt = GPR[RT];
463  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
464  GPR[RD] = rs >> 8 * (8 - IMMEDIATE) | rt << 8 * IMMEDIATE;
465  TRACE_ALU_RESULT (GPR[RD]);
466}
467
468011111,00000,5.RT,5.RD,00000,100000:POOL32X:32::BITSWAP
469"bitswap r<RD>, r<RT>"
470*mips32r6:
471*mips64r6:
472{
473  /* Taken from: http://graphics.stanford.edu/~seander/bithacks.html */
474  uint32_t v = GPR[RT];
475
476  TRACE_ALU_INPUT1 (v);
477  v = ((v >> 1)  & 0x55555555) | ((v & 0x55555555) << 1);
478  v = ((v >> 2)  & 0x33333333) | ((v & 0x33333333) << 2);
479  v = ((v >> 4)  & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
480  GPR[RD] = EXTEND32 (v);
481  TRACE_ALU_RESULT(GPR[RD]);
482}
483
484011111,00000,5.RT,5.RD,00000,100100:POOL32X:64::DBITSWAP
485"dbitswap r<RD>, r<RT>"
486*mips64r6:
487{
488  /* Taken from: http://graphics.stanford.edu/~seander/bithacks.html */
489  uint64_t v = GPR[RT];
490
491  TRACE_ALU_INPUT1 (v);
492  v = ((v >> 1)  & 0x5555555555555555) | ((v & 0x5555555555555555) << 1);
493  v = ((v >> 2)  & 0x3333333333333333) | ((v & 0x3333333333333333) << 2);
494  v = ((v >> 4)  & 0x0F0F0F0F0F0F0F0F) | ((v & 0x0F0F0F0F0F0F0F0F) << 4);
495  TRACE_ALU_RESULT(v);
496  GPR[RD] = v;
497}
498
499111011,5.RS,00,19.IMMEDIATE:POOL32X:32::ADDIUPC
500"addiupc r<RS>, <IMMEDIATE>"
501*mips32r6:
502*mips64r6:
503{
504  TRACE_ALU_INPUT1 (IMMEDIATE);
505  GPR[RS] = loadstore_ea (SD_, CIA, EXTEND19 (IMMEDIATE) << 2);
506  TRACE_ALU_RESULT (GPR[RS]);
507}
508
509111011,5.RS,11110,16.IMMEDIATE:POOL32X:32::AUIPC
510"auipc r<RS>, <IMMEDIATE>"
511*mips32r6:
512*mips64r6:
513{
514  TRACE_ALU_INPUT1 (IMMEDIATE);
515  GPR[RS] = loadstore_ea (SD_, CIA, EXTEND32 (IMMEDIATE << 16));
516  TRACE_ALU_RESULT (GPR[RS]);
517}
518
519111011,5.RS,11111,16.IMMEDIATE:POOL32X:32::ALUIPC
520"aluipc r<RS>, <IMMEDIATE>"
521*mips32r6:
522*mips64r6:
523{
524  TRACE_ALU_INPUT1 (IMMEDIATE);
525  GPR[RS] = ~0x0FFFF & loadstore_ea (SD_, CIA, EXTEND32 (IMMEDIATE << 16));
526  TRACE_ALU_RESULT (GPR[RS]);
527}
528
529111011,5.RS,01,19.IMMEDIATE:POOL32X:32::LWPC
530"lwpc r<RS>, <IMMEDIATE>"
531*mips32r6:
532*mips64r6:
533{
534  uint32_t offset = EXTEND19 (IMMEDIATE) << 2;
535  TRACE_ALU_INPUT1 (IMMEDIATE);
536  GPR[RS] = EXTEND32 (do_load (SD_, AccessLength_WORD, CIA, offset));
537  TRACE_ALU_RESULT (GPR[RS]);
538}
539
540111011,5.RS,10,19.IMMEDIATE:POOL32X:64::LWUPC
541"lwupc r<RS>, <IMMEDIATE>"
542*mips64r6:
543{
544  uint32_t offset = EXTEND19 (IMMEDIATE) << 2;
545  TRACE_ALU_INPUT1 (CIA + offset);
546  GPR[RS] = do_load (SD_, AccessLength_WORD, CIA, offset);
547  TRACE_ALU_RESULT (GPR[RS]);
548}
549
550111011,5.RS,110,18.IMMEDIATE:POOL32X:64::LDPC
551"ldpc r<RS>, <IMMEDIATE>"
552*mips64r6:
553{
554  uint32_t offset = EXTEND18 (IMMEDIATE) << 3;
555  TRACE_ALU_INPUT1 (IMMEDIATE);
556  GPR[RS] = do_load (SD_, AccessLength_DOUBLEWORD, CIA, offset);
557  TRACE_ALU_RESULT (GPR[RS]);
558}
559010001,1000,1.FMT,00000,5.FS,5.FD,011010::32,64,f::RINT.fmt
560"rint.%s<FMT> f<FD>, f<FS>"
561*mips32r6:
562*mips64r6:
563{
564  uint64_t result;
565  int fmt = FMT;
566  check_fpu (SD_);
567  check_u64 (SD_, instruction_0);
568  check_fmt_p (SD_, fmt, instruction_0);
569  TRACE_ALU_INPUT1 (FGR[FS]);
570  RoundToIntegralExact (ValueFPR (FS, fmt), &result, fmt);
571  StoreFPR (FD, fmt, result);
572  TRACE_ALU_RESULT (FGR[FD]);
573}
574
575010001,1000,1.FMT,00000,5.FS,5.FD,011011::32,64,f::CLASS.fmt
576"class.%s<FMT> f<FD>, f<FS>"
577*mips32r6:
578*mips64r6:
579{
580  int fmt = FMT;
581  check_fpu (SD_);
582  check_u64 (SD_, instruction_0);
583  check_fmt_p (SD_, fmt, instruction_0);
584  StoreFPR (FD, fmt, Classify (ValueFPR (FS, fmt), fmt));
585}
586
587010001,1000,1.FMT,5.FT,5.FS,5.FD,011100::32,64,f::MIN.fmt
588"min.%s<FMT> f<FD>, f<FS>, f<FT>"
589*mips32r6:
590*mips64r6:
591{
592  int fmt = FMT;
593  check_fpu (SD_);
594  check_u64 (SD_, instruction_0);
595  check_fmt_p (SD_, fmt, instruction_0);
596  TRACE_ALU_INPUT2 (FGR[FS], FGR[FT]);
597  StoreFPR (FD, fmt, Min (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
598  TRACE_ALU_RESULT (FGR[FD]);
599}
600
601010001,1000,1.FMT,5.FT,5.FS,5.FD,011110::32,64,f::MAX.fmt
602"max.%s<FMT> f<FD>, f<FS>, f<FT>"
603*mips32r6:
604*mips64r6:
605{
606  int fmt = FMT;
607  check_fpu (SD_);
608  check_u64 (SD_, instruction_0);
609  check_fmt_p (SD_, fmt, instruction_0);
610  TRACE_ALU_INPUT2 (FGR[FS], FGR[FT]);
611  StoreFPR (FD, fmt, Max (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
612  TRACE_ALU_RESULT (FGR[FD]);
613}
614
615010001,1000,1.FMT,5.FT,5.FS,5.FD,011101::32,64,f::MINA.fmt
616"mina.%s<FMT> f<FD>, f<FS>, f<FT>"
617*mips32r6:
618*mips64r6:
619{
620  int fmt = FMT;
621  check_fpu (SD_);
622  check_u64 (SD_, instruction_0);
623  check_fmt_p (SD_, fmt, instruction_0);
624  TRACE_ALU_INPUT2 (FGR[FS], FGR[FT]);
625  StoreFPR (FD, fmt, MinA (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
626  TRACE_ALU_RESULT (FGR[FD]);
627}
628
629010001,1000,1.FMT,5.FT,5.FS,5.FD,011111::32,64,f::MAXA.fmt
630"maxa.%s<FMT> f<FD>, f<FS>, f<FT>"
631*mips32r6:
632*mips64r6:
633{
634  int fmt = FMT;
635  check_fpu (SD_);
636  check_u64 (SD_, instruction_0);
637  check_fmt_p (SD_, fmt, instruction_0);
638  TRACE_ALU_INPUT2 (FGR[FS], FGR[FT]);
639  StoreFPR (FD, fmt, MaxA (ValueFPR (FS, fmt), ValueFPR (FT, fmt), fmt));
640  TRACE_ALU_RESULT (FGR[FD]);
641}
642000000,5.RS,5.RT,5.RD,00010,011000:POOL32X:32::MUL
643"mul r<RD>, r<RS>, r<RT>"
644*mips32r6:
645*mips64r6:
646{
647  int64_t prod;
648  if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
649    Unpredictable ();
650  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
651  prod = ((int64_t)(int32_t) GPR[RS])
652    * ((int64_t)(int32_t) GPR[RT]);
653  GPR[RD] = EXTEND32 (VL4_8 (prod));
654  TRACE_ALU_RESULT (GPR[RD]);
655}
656
657000000,5.RS,5.RT,5.RD,00011,011000:POOL32X:32::MUH
658"muh r<RD>, r<RS>, r<RT>"
659*mips32r6:
660*mips64r6:
661{
662  int64_t prod;
663  if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
664    Unpredictable ();
665  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
666  prod = ((int64_t)(int32_t) GPR[RS])
667    * ((int64_t)(int32_t) GPR[RT]);
668  GPR[RD] = EXTEND32 (VH4_8 (prod));
669  TRACE_ALU_RESULT (GPR[RD]);
670}
671
672000000,5.RS,5.RT,5.RD,00010,011001:POOL32X:32::MULU
673"mulu r<RD>, r<RS>, r<RT>"
674*mips32r6:
675*mips64r6:
676{
677  uint64_t prod;
678  if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
679    Unpredictable ();
680  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
681  prod = ((uint64_t)(uint32_t) GPR[RS])
682    * ((uint64_t)(uint32_t) GPR[RT]);
683  GPR[RD] = EXTEND32 (VL4_8 (prod));
684  TRACE_ALU_RESULT (GPR[RD]);
685}
686
687000000,5.RS,5.RT,5.RD,00011,011001:POOL32X:32::MUHU
688"muhu r<RD>, r<RS>, r<RT>"
689*mips32r6:
690*mips64r6:
691{
692  uint64_t prod;
693  if (NotWordValue (GPR[RS]) || NotWordValue (GPR[RT]))
694    Unpredictable ();
695  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
696  prod = ((uint64_t)(uint32_t) GPR[RS])
697    * ((uint64_t)(uint32_t) GPR[RT]);
698  GPR[RD] = EXTEND32 (VH4_8 (prod));
699  TRACE_ALU_RESULT (GPR[RD]);
700}
701
702000000,5.RS,5.RT,5.RD,00010,011010:POOL32X:32::DIV
703"div r<RD>, r<RS>, r<RT>"
704*mips32r6:
705*mips64r6:
706{
707  int32_t n = GPR[RS];
708  int32_t d = GPR[RT];
709  TRACE_ALU_INPUT2 (n,d);
710  if (d == 0)
711    GPR[RD] = EXTEND32 (0x80000000);
712  else if (n == SIGNED32 (0x80000000) && d == -1)
713    GPR[RD] = EXTEND32 (0x80000000);
714  else
715    GPR[RD] = EXTEND32 (n / d);
716
717  TRACE_ALU_RESULT (GPR[RD]);
718}
719
720000000,5.RS,5.RT,5.RD,00011,011010:POOL32X:32::MOD
721"mod r<RD>, r<RS>, r<RT>"
722*mips32r6:
723*mips64r6:
724{
725  int32_t n = GPR[RS];
726  int32_t d = GPR[RT];
727  TRACE_ALU_INPUT2 (n,d);
728  if (d == 0 || (n == SIGNED32 (0x80000000) && d == -1))
729    GPR[RD] = EXTEND32 (0);
730  else
731    GPR[RD] = EXTEND32 (n % d);
732
733  TRACE_ALU_RESULT (GPR[RD]);
734}
735
736000000,5.RS,5.RT,5.RD,00010,011011:POOL32X:32::DIVU
737"divu r<RD>, r<RS>, r<RT>"
738*mips32r6:
739*mips64r6:
740{
741  uint32_t n = GPR[RS];
742  uint32_t d = GPR[RT];
743  TRACE_ALU_INPUT2 (n,d);
744  if (d == 0)
745    GPR[RD] = EXTEND32 (0x80000000);
746  else
747    GPR[RD] = EXTEND32 (n / d);
748
749  TRACE_ALU_RESULT (GPR[RD]);
750}
751
752000000,5.RS,5.RT,5.RD,00011,011011:POOL32X:32::MODU
753"modu r<RD>, r<RS>, r<RT>"
754*mips32r6:
755*mips64r6:
756{
757  uint32_t n = GPR[RS];
758  uint32_t d = GPR[RT];
759  TRACE_ALU_INPUT2 (n,d);
760  if (d == 0)
761    GPR[RD] = EXTEND32 (0);
762  else
763    GPR[RD] = EXTEND32 (n % d);
764
765  TRACE_ALU_RESULT (GPR[RD]);
766}
767
768000000,5.RS,5.RT,5.RD,00010,011100:POOL32X:64::DMUL
769"dmul r<RD>, r<RS>, r<RT>"
770*mips64r6:
771{
772  uint64_t lo;
773  uint64_t m00;
774  uint64_t m01;
775  uint64_t m10;
776  uint64_t mid;
777  int sign;
778  uint64_t op1 = GPR[RS];
779  uint64_t op2 = GPR[RT];
780
781  check_u64 (SD_, instruction_0);
782  TRACE_ALU_INPUT2 (op1, op2);
783  /* make signed multiply unsigned */
784  sign = 0;
785  if ((int64_t) op1 < 0)
786    {
787      op1 = - op1;
788      ++sign;
789    }
790  if ((int64_t) op2 < 0)
791    {
792      op2 = - op2;
793      ++sign;
794    }
795  /* multiply out the sub products */
796  m00 = ((uint64_t) VL4_8 (op1) * (uint64_t) VL4_8 (op2));
797  m10 = ((uint64_t) VH4_8 (op1) * (uint64_t) VL4_8 (op2));
798  m01 = ((uint64_t) VL4_8 (op1) * (uint64_t) VH4_8 (op2));
799  /* add the products */
800  mid = ((uint64_t) VH4_8 (m00)
801	 + (uint64_t) VL4_8 (m10)
802	 + (uint64_t) VL4_8 (m01));
803  lo = U8_4 (mid, m00);
804  /* fix the sign */
805  if (sign & 1)
806    lo = -lo;
807
808  GPR[RD] = lo;
809  TRACE_ALU_RESULT (GPR[RD]);
810}
811
812000000,5.RS,5.RT,5.RD,00011,011100:POOL32X:64::DMUH
813"dmuh r<RD>, r<RS>, r<RT>"
814*mips64r6:
815{
816  uint64_t lo;
817  uint64_t hi;
818  uint64_t m00;
819  uint64_t m01;
820  uint64_t m10;
821  uint64_t m11;
822  uint64_t mid;
823  int sign;
824  uint64_t op1 = GPR[RS];
825  uint64_t op2 = GPR[RT];
826
827  check_u64 (SD_, instruction_0);
828  TRACE_ALU_INPUT2 (op1, op2);
829  /* make signed multiply unsigned */
830  sign = 0;
831  if ((int64_t) op1 < 0)
832    {
833      op1 = - op1;
834      ++sign;
835    }
836  if ((int64_t) op2 < 0)
837    {
838      op2 = - op2;
839      ++sign;
840    }
841  /* multiply out the 4 sub products */
842  m00 = ((uint64_t) VL4_8 (op1) * (uint64_t) VL4_8 (op2));
843  m10 = ((uint64_t) VH4_8 (op1) * (uint64_t) VL4_8 (op2));
844  m01 = ((uint64_t) VL4_8 (op1) * (uint64_t) VH4_8 (op2));
845  m11 = ((uint64_t) VH4_8 (op1) * (uint64_t) VH4_8 (op2));
846  /* add the products */
847  mid = ((uint64_t) VH4_8 (m00)
848	 + (uint64_t) VL4_8 (m10)
849	 + (uint64_t) VL4_8 (m01));
850  lo = U8_4 (mid, m00);
851  hi = (m11
852	+ (uint64_t) VH4_8 (mid)
853	+ (uint64_t) VH4_8 (m01)
854	+ (uint64_t) VH4_8 (m10));
855  /* fix the sign */
856  if (sign & 1)
857    {
858      lo = -lo;
859      if (lo == 0)
860	hi = -hi;
861      else
862	hi = -hi - 1;
863    }
864
865  GPR[RD] = hi;
866  TRACE_ALU_RESULT (GPR[RD]);
867}
868
869000000,5.RS,5.RT,5.RD,00010,011101:POOL32X:64::DMULU
870"dmulu r<RD>, r<RS>, r<RT>"
871*mips64r6:
872{
873  uint64_t lo;
874  uint64_t m00;
875  uint64_t m01;
876  uint64_t m10;
877  uint64_t mid;
878  uint64_t op1 = GPR[RS];
879  uint64_t op2 = GPR[RT];
880
881  check_u64 (SD_, instruction_0);
882  TRACE_ALU_INPUT2 (op1, op2);
883  /* multiply out the sub products */
884  m00 = ((uint64_t) VL4_8 (op1) * (uint64_t) VL4_8 (op2));
885  m10 = ((uint64_t) VH4_8 (op1) * (uint64_t) VL4_8 (op2));
886  m01 = ((uint64_t) VL4_8 (op1) * (uint64_t) VH4_8 (op2));
887  /* add the products */
888  mid = ((uint64_t) VH4_8 (m00)
889	 + (uint64_t) VL4_8 (m10)
890	 + (uint64_t) VL4_8 (m01));
891  lo = U8_4 (mid, m00);
892
893  GPR[RD] = lo;
894  TRACE_ALU_RESULT (GPR[RD]);
895}
896
897000000,5.RS,5.RT,5.RD,00011,011101:POOL32X:64::DMUHU
898"dmuhu r<RD>, r<RS>, r<RT>"
899*mips64r6:
900{
901  uint64_t lo;
902  uint64_t hi;
903  uint64_t m00;
904  uint64_t m01;
905  uint64_t m10;
906  uint64_t m11;
907  uint64_t mid;
908  uint64_t op1 = GPR[RS];
909  uint64_t op2 = GPR[RT];
910
911  check_u64 (SD_, instruction_0);
912  TRACE_ALU_INPUT2 (op1, op2);
913  /* multiply out the 4 sub products */
914  m00 = ((uint64_t) VL4_8 (op1) * (uint64_t) VL4_8 (op2));
915  m10 = ((uint64_t) VH4_8 (op1) * (uint64_t) VL4_8 (op2));
916  m01 = ((uint64_t) VL4_8 (op1) * (uint64_t) VH4_8 (op2));
917  m11 = ((uint64_t) VH4_8 (op1) * (uint64_t) VH4_8 (op2));
918  /* add the products */
919  mid = ((uint64_t) VH4_8 (m00)
920	 + (uint64_t) VL4_8 (m10)
921	 + (uint64_t) VL4_8 (m01));
922  lo = U8_4 (mid, m00);
923  hi = (m11
924	+ (uint64_t) VH4_8 (mid)
925	+ (uint64_t) VH4_8 (m01)
926	+ (uint64_t) VH4_8 (m10));
927
928  GPR[RD] = hi;
929  TRACE_ALU_RESULT (GPR[RD]);
930}
931
932000000,5.RS,5.RT,5.RD,00010,011110:POOL32X:64::DDIV
933"ddiv r<RD>, r<RS>, r<RT>"
934*mips64r6:
935{
936  int64_t n = GPR[RS];
937  int64_t d = GPR[RT];
938
939  check_u64 (SD_, instruction_0);
940  TRACE_ALU_INPUT2 (n, d);
941  if (d == 0)
942    GPR[RD] = SIGNED64 (0x8000000000000000);
943  else if (d == -1 && n == SIGNED64 (0x8000000000000000))
944    GPR[RD] = SIGNED64 (0x8000000000000000);
945  else
946    GPR[RD] = (n / d);
947
948  TRACE_ALU_RESULT (GPR[RD]);
949}
950
951000000,5.RS,5.RT,5.RD,00011,011110:POOL32X:64::DMOD
952"dmod r<RD>, r<RS>, r<RT>"
953*mips64r6:
954{
955  int64_t n = GPR[RS];
956  int64_t d = GPR[RT];
957
958  check_u64 (SD_, instruction_0);
959  TRACE_ALU_INPUT2 (n, d);
960  if (d == 0 || (d == -1 && n == SIGNED64 (0x8000000000000000)))
961    GPR[RD] = SIGNED64 (0);
962  else
963    GPR[RD] = (n % d);
964
965  TRACE_ALU_RESULT (GPR[RD]);
966}
967
968000000,5.RS,5.RT,5.RD,00010,011111:POOL32X:64::DDIVU
969"ddivu r<RD>, r<RS>, r<RT>"
970*mips64r6:
971{
972  uint64_t n = GPR[RS];
973  uint64_t d = GPR[RT];
974
975  check_u64 (SD_, instruction_0);
976  TRACE_ALU_INPUT2 (n, d);
977  if (d == 0)
978    GPR[RD] = UNSIGNED64 (0x8000000000000000);
979  else
980    GPR[RD] = (n / d);
981
982  TRACE_ALU_RESULT (GPR[RD]);
983}
984
985000000,5.RS,5.RT,5.RD,00011,011111:POOL32X:64::DMODU
986"dmodu r<RD>, r<RS>, r<RT>"
987*mips64r6:
988{
989  uint64_t n = GPR[RS];
990  uint64_t d = GPR[RT];
991
992  check_u64 (SD_, instruction_0);
993  TRACE_ALU_INPUT2 (n, d);
994  if (d == 0)
995    GPR[RD] = UNSIGNED64 (0);
996  else
997    GPR[RD] = (n % d);
998
999  TRACE_ALU_RESULT (GPR[RD]);
1000}
1001
1002011111,5.BASE,5.RT,9.OFFSET,0,110110:SPECIAL3:32::LL
1003"ll r<RT>, <OFFSET>(r<BASE>)"
1004*mips32r6:
1005*mips64r6:
1006{
1007  do_ll (SD_, RT, EXTEND9 (OFFSET), BASE);
1008}
1009
1010011111,5.BASE,5.RT,5.RD,0000,1,110110:SPECIAL3:32::LLWP
1011"llwp r<RT>, r<RD>, (r<BASE>)"
1012*mips32r6:
1013*mips64r6:
1014{
1015  int first, second;
1016  int offset;
1017
1018  if (RT == BASE)
1019  {
1020    first = RD;
1021    second = RT;
1022    offset = BigEndianCPU ? 0 : 4;
1023  }
1024  else
1025  {
1026    first = RT;
1027    second = RD;
1028    offset = BigEndianCPU ? 4 : 0;
1029  }
1030
1031  do_ll (SD_, first, offset, BASE);
1032  do_ll (SD_, second, offset ^ 4, BASE);
1033}
1034
1035
1036011111,5.BASE,5.RT,9.OFFSET,0,100110:SPECIAL3:32::SC
1037"sc r<RT>, <OFFSET>(r<BASE>)"
1038*mips32r6:
1039*mips64r6:
1040{
1041  do_sc (SD_, RT, EXTEND9 (OFFSET), BASE, instruction_0, 1);
1042}
1043
1044011111,5.BASE,5.RT,9.OFFSET,0,110111:SPECIAL3:64::LLD
1045"lld r<RT>, <OFFSET>(r<BASE>)"
1046*mips64r6:
1047{
1048  check_u64 (SD_, instruction_0);
1049  do_lld (SD_, RT, EXTEND9 (OFFSET), BASE);
1050}
1051
1052
1053011111,5.BASE,5.RT,5.RD,0000,1,100110:SPECIAL3:32::SCWP
1054"scwp r<RT>, r<RD>, (r<BASE>)"
1055*mips32r6:
1056*mips64r6:
1057{
1058  int offset = BigEndianCPU ? 0 : 4;
1059
1060  do_sc (SD_, RD, offset, BASE, instruction_0, 0);
1061  do_sc (SD_, RT, offset ^ 4, BASE, instruction_0, 1);
1062}
1063
1064011111,5.BASE,5.RT,5.RD,0000,1,110111:SPECIAL3:64::LLDP
1065"lldp r<RT>, r<RD>, (r<BASE>)"
1066*mips64r6:
1067{
1068  int first, second;
1069  int offset;
1070
1071  check_u64 (SD_, instruction_0);
1072
1073  if (RT == BASE)
1074  {
1075    first = RD;
1076    second = RT;
1077    offset = BigEndianCPU ? 0 : 8;
1078  }
1079  else
1080  {
1081    first = RT;
1082    second = RD;
1083    offset = BigEndianCPU ? 8 : 0;
1084  }
1085
1086  do_lld (SD_, first, offset, BASE);
1087  do_lld (SD_, second, offset ^ 8, BASE);
1088}
1089
1090011111,5.BASE,5.RT,9.OFFSET,0,100111:SPECIAL3:64::SCD
1091"scd r<RT>, <OFFSET>(r<BASE>)"
1092*mips64r6:
1093{
1094  check_u64 (SD_, instruction_0);
1095  do_scd (SD_, RT, EXTEND9 (OFFSET), BASE, 1);
1096}
1097
1098011111,5.BASE,5.RT,5.RD,0000,1,100111:SPECIAL3:64::SCDP
1099"scdp r<RT>, r<RD>, (r<BASE>)"
1100*mips64r6:
1101{
1102  int offset = BigEndianCPU ? 0 : 8;
1103  check_u64 (SD_, instruction_0);
1104
1105  do_scd (SD_, RD, offset, BASE, 0);
1106  do_scd (SD_, RT, offset ^ 8, BASE, 1);
1107}
1108
1109011111,5.BASE,5.HINT,9.OFFSET,0,110101:SPECIAL3:32::PREF
1110"pref <HINT>, <OFFSET>(r<BASE>)"
1111*mips32r6:
1112*mips64r6:
1113{
1114  do_pref (SD_, HINT, EXTEND9 (OFFSET), BASE);
1115}
1116
1117011111,5.BASE,5.HINT,9.OFFSET,0,100101:SPECIAL3:32::CACHE
1118"cache <HINT>, <OFFSET>(r<BASE>)"
1119*mips32r6:
1120*mips64r6:
1121{
1122  do_cache (SD_, HINT, BASE, EXTEND9 (OFFSET), instruction_0);
1123}
1124
1125
1126000000,5.RS,00000,5.RD,00001,010000:POOL32X:32::CLZ
1127"clz r<RD>, r<RS>"
1128*mips32r6:
1129*mips64r6:
1130{
1131  do_clz (SD_, RD, RS);
1132}
1133
1134000000,5.RS,00000,5.RD,00001,010001:POOL32X:32::CLO
1135"clo r<RD>, r<RS>"
1136*mips32r6:
1137*mips64r6:
1138{
1139  do_clo (SD_, RD, RS);
1140}
1141
1142000000,5.RS,00000,5.RD,00001,010010:POOL32X:64::DCLZ
1143"dclz r<RD>, r<RS>"
1144*mips64r6:
1145{
1146  check_u64 (SD_, instruction_0);
1147  do_dclz (SD_, RD, RS);
1148}
1149
1150000000,5.RS,00000,5.RD,00001,010011:POOL32X:64::DCLO
1151"dclo r<RD>, r<RS>"
1152*mips64r6:
1153{
1154  check_u64 (SD_, instruction_0);
1155  do_dclo (SD_, RD, RS);
1156}
1157010001,1000,1.FMT,5.FT,5.FS,5.FD,010000:POOL32X:32,f::SEL.fmt
1158"sel.%s<FMT> f<FD>, f<FS>, f<FT>"
1159*mips32r6:
1160*mips64r6:
1161{
1162  check_fpu (SD_);
1163  check_fmt_p (SD_, FMT, instruction_0);
1164  TRACE_ALU_INPUT3 (FGR[FD], ValueFPR(FS, FMT), ValueFPR(FT, FMT));
1165  if ((FGR[FD] & 0x01) != 0)
1166    StoreFPR (FD, FMT, ValueFPR (FT, FMT));
1167  else
1168    StoreFPR (FD, FMT, ValueFPR (FS, FMT));
1169  TRACE_ALU_RESULT (ValueFPR(FD, FMT));
1170}
1171
1172010001,1000,1.FMT,5.FT,5.FS,5.FD,010100:POOL32X:32,f::SELEQZ.fmt
1173"seleqz.%s<FMT> f<FD>, f<FS>, f<FT>"
1174*mips32r6:
1175*mips64r6:
1176{
1177  check_fpu (SD_);
1178  check_fmt_p (SD_, FMT, instruction_0);
1179  TRACE_ALU_INPUT2 (ValueFPR(FS, FMT), FGR[FT]);
1180  if ((FGR[FT] & 0x01) == 0)
1181    StoreFPR (FD, FMT, ValueFPR (FS, FMT));
1182  else
1183    StoreFPR (FD, FMT, 0);
1184  TRACE_ALU_RESULT (ValueFPR(FD, FMT));
1185}
1186
1187010001,1000,1.FMT,5.FT,5.FS,5.FD,010111:POOL32X:32,f::SELNEZ.fmt
1188"selnez.%s<FMT> f<FD>, f<FS>, f<FT>"
1189*mips32r6:
1190*mips64r6:
1191{
1192  check_fpu (SD_);
1193  check_fmt_p (SD_, FMT, instruction_0);
1194  TRACE_ALU_INPUT2 (ValueFPR(FS, FMT), FGR[FT]);
1195  if ((FGR[FT] & 0x01) == 0)
1196    StoreFPR (FD, FMT, 0);
1197  else
1198    StoreFPR (FD, FMT, ValueFPR (FS, FMT));
1199  TRACE_ALU_RESULT (ValueFPR(FD, FMT));
1200}
1201
1202000000,5.RS,5.RT,5.RD,00000,110101:POOL32X:32::SELEQZ
1203"seleqz r<RD>, r<RS>, r<RT>"
1204*mips32r6:
1205*mips64r6:
1206{
1207  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
1208  if (GPR[RT] != 0)
1209    GPR[RD] = 0;
1210  else
1211    GPR[RD] = GPR[RS];
1212  TRACE_ALU_RESULT (GPR[RD]);
1213}
1214
1215000000,5.RS,5.RT,5.RD,00000,110111:POOL32X:32::SELNEZ
1216"selnez r<RD>, r<RS>, r<RT>"
1217*mips32r6:
1218*mips64r6:
1219{
1220  TRACE_ALU_INPUT2 (GPR[RS], GPR[RT]);
1221  if (GPR[RT] != 0)
1222    GPR[RD] = GPR[RS];
1223  else
1224    GPR[RD] = 0;
1225  TRACE_ALU_RESULT (GPR[RD]);
1226}
1227