cpu_alpha_instr.cc Source File

Back to the index.

cpu_alpha_instr.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2018 Anders Gavare. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. The name of the author may not be used to endorse or promote products
13  * derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  *
28  * Alpha instructions.
29  *
30  * Individual functions should keep track of cpu->n_translated_instrs.
31  * (If no instruction was executed, then it should be decreased. If, say, 4
32  * instructions were combined into one function and executed, then it should
33  * be increased by 3.)
34  */
35 
36 
37 #include "float_emul.h"
38 
39 
40 /*
41  * nop: Do nothing.
42  */
44 {
45 }
46 
47 
48 /*
49  * call_pal: PALcode call
50  *
51  * arg[0] = pal nr
52  */
53 X(call_pal)
54 {
55  /* Synchronize PC first: */
56  uint64_t old_pc, low_pc = ((size_t)ic - (size_t)
57  cpu->cd.alpha.cur_ic_page) / sizeof(struct alpha_instr_call);
58  cpu->pc &= ~((ALPHA_IC_ENTRIES_PER_PAGE-1) <<
60  cpu->pc += (low_pc << ALPHA_INSTR_ALIGNMENT_SHIFT);
61  old_pc = cpu->pc;
62 
63  alpha_palcode(cpu, ic->arg[0]);
64 
65  if (!cpu->running) {
67  cpu->cd.alpha.next_ic = &nothing_call;
68  } else if (cpu->pc != old_pc) {
69  /* The PC value was changed by the palcode call. */
70  /* Find the new physical page and update the translation
71  pointers: */
72  alpha_pc_to_pointers(cpu);
73  }
74 }
75 
76 
77 /*
78  * jsr: Jump to SubRoutine
79  *
80  * arg[0] = ptr to uint64_t where to store return PC
81  * arg[1] = ptr to uint64_t of new PC
82  */
83 X(jsr)
84 {
85  uint64_t old_pc = cpu->pc, low_pc;
86  uint64_t mask_within_page = ((ALPHA_IC_ENTRIES_PER_PAGE-1)
88  ((1 << ALPHA_INSTR_ALIGNMENT_SHIFT) - 1);
89 
90  low_pc = ((size_t)ic - (size_t)
91  cpu->cd.alpha.cur_ic_page) / sizeof(struct alpha_instr_call);
94  cpu->pc += (low_pc << ALPHA_INSTR_ALIGNMENT_SHIFT) + 4;
95 
96  *((int64_t *)ic->arg[0]) = cpu->pc;
97  cpu->pc = *((int64_t *)ic->arg[1]);
98 
99  /*
100  * If this is a jump/return into the same code page as we were
101  * already in, then just set cpu->cd.alpha.next_ic.
102  */
103  if ((old_pc & ~mask_within_page) == (cpu->pc & ~mask_within_page)) {
104  cpu->cd.alpha.next_ic = cpu->cd.alpha.cur_ic_page +
105  ((cpu->pc & mask_within_page) >> 2);
106  } else {
107  /* Find the new physical page and update pointers: */
108  alpha_pc_to_pointers(cpu);
109  }
110 }
111 
112 
113 /*
114  * jsr_trace: Jump to SubRoutine (with function call trace enabled)
115  *
116  * Arguments same as for jsr.
117  */
118 X(jsr_trace)
119 {
120  cpu_functioncall_trace(cpu, *((int64_t *)ic->arg[1]));
121  instr(jsr)(cpu, ic);
122 }
123 
124 
125 /*
126  * jsr_0: JSR/RET, don't store return PC.
127  *
128  * arg[0] = ignored
129  * arg[1] = ptr to uint64_t of new PC
130  */
131 X(jsr_0)
132 {
133  uint64_t old_pc = cpu->pc;
134  uint64_t mask_within_page = ((ALPHA_IC_ENTRIES_PER_PAGE-1)
136  | ((1 << ALPHA_INSTR_ALIGNMENT_SHIFT) - 1);
137 
138  cpu->pc = *((int64_t *)ic->arg[1]);
139 
140  /*
141  * If this is a jump/return into the same code page as we were
142  * already in, then just set cpu->cd.alpha.next_ic.
143  */
144  if ((old_pc & ~mask_within_page) == (cpu->pc & ~mask_within_page)) {
145  cpu->cd.alpha.next_ic = cpu->cd.alpha.cur_ic_page +
146  ((cpu->pc & mask_within_page) >> 2);
147  } else {
148  /* Find the new physical page and update pointers: */
149  alpha_pc_to_pointers(cpu);
150  }
151 }
152 
153 
154 /*
155  * jsr_0_trace: JSR/RET (with function call trace enabled)
156  *
157  * Arguments same as for jsr_0.
158  */
159 X(jsr_0_trace)
160 {
162  instr(jsr_0)(cpu, ic);
163 }
164 
165 
166 /*
167  * br: Branch (to a different translated page)
168  *
169  * arg[0] = relative offset (as an int32_t)
170  */
171 X(br)
172 {
173  uint64_t low_pc;
174 
175  /* Calculate new PC from this instruction + arg[0] */
176  low_pc = ((size_t)ic - (size_t)
177  cpu->cd.alpha.cur_ic_page) / sizeof(struct alpha_instr_call);
180  cpu->pc += (low_pc << ALPHA_INSTR_ALIGNMENT_SHIFT);
181  cpu->pc += (int32_t)ic->arg[0];
182 
183  /* Find the new physical page and update the translation pointers: */
184  alpha_pc_to_pointers(cpu);
185 }
186 
187 
188 /*
189  * br: Branch (to a different translated page), write return address
190  *
191  * arg[0] = relative offset (as an int32_t)
192  * arg[1] = pointer to uint64_t where to write return address
193  */
194 X(br_return)
195 {
196  uint64_t low_pc;
197 
198  /* Calculate new PC from this instruction + arg[0] */
199  low_pc = ((size_t)ic - (size_t)
200  cpu->cd.alpha.cur_ic_page) / sizeof(struct alpha_instr_call);
203  cpu->pc += (low_pc << ALPHA_INSTR_ALIGNMENT_SHIFT);
204 
205  /* ... but first, save away the return address: */
206  *((int64_t *)ic->arg[1]) = cpu->pc + 4;
207 
208  cpu->pc += (int32_t)ic->arg[0];
209 
210  /* Find the new physical page and update the translation pointers: */
211  alpha_pc_to_pointers(cpu);
212 }
213 
214 
215 /*
216  * beq: Branch (to a different translated page) if Equal
217  *
218  * arg[0] = relative offset (as an int32_t)
219  * arg[1] = pointer to int64_t register
220  */
221 X(beq)
222 {
223  if (*((int64_t *)ic->arg[1]) == 0)
224  instr(br)(cpu, ic);
225 }
226 
227 
228 /*
229  * blbs: Branch (to a different translated page) if Low Bit Set
230  *
231  * arg[0] = relative offset (as an int32_t)
232  * arg[1] = pointer to int64_t register
233  */
234 X(blbs)
235 {
236  if (*((int64_t *)ic->arg[1]) & 1)
237  instr(br)(cpu, ic);
238 }
239 
240 
241 /*
242  * blbc: Branch (to a different translated page) if Low Bit Clear
243  *
244  * arg[0] = relative offset (as an int32_t)
245  * arg[1] = pointer to int64_t register
246  */
247 X(blbc)
248 {
249  if (!(*((int64_t *)ic->arg[1]) & 1))
250  instr(br)(cpu, ic);
251 }
252 
253 
254 /*
255  * bne: Branch (to a different translated page) if Not Equal
256  *
257  * arg[0] = relative offset (as an int32_t)
258  * arg[1] = pointer to int64_t register
259  */
260 X(bne)
261 {
262  if (*((int64_t *)ic->arg[1]) != 0)
263  instr(br)(cpu, ic);
264 }
265 
266 
267 /*
268  * ble: Branch (to a different translated page) if Less or Equal
269  *
270  * arg[0] = relative offset (as an int32_t)
271  * arg[1] = pointer to int64_t register
272  */
273 X(ble)
274 {
275  if (*((int64_t *)ic->arg[1]) <= 0)
276  instr(br)(cpu, ic);
277 }
278 
279 
280 /*
281  * blt: Branch (to a different translated page) if Less Than
282  *
283  * arg[0] = relative offset (as an int32_t)
284  * arg[1] = pointer to int64_t register
285  */
286 X(blt)
287 {
288  if (*((int64_t *)ic->arg[1]) < 0)
289  instr(br)(cpu, ic);
290 }
291 
292 
293 /*
294  * bge: Branch (to a different translated page) if Greater or Equal
295  *
296  * arg[0] = relative offset (as an int32_t)
297  * arg[1] = pointer to int64_t register
298  */
299 X(bge)
300 {
301  if (*((int64_t *)ic->arg[1]) >= 0)
302  instr(br)(cpu, ic);
303 }
304 
305 
306 /*
307  * bgt: Branch (to a different translated page) if Greater Than
308  *
309  * arg[0] = relative offset (as an int32_t)
310  * arg[1] = pointer to int64_t register
311  */
312 X(bgt)
313 {
314  if (*((int64_t *)ic->arg[1]) > 0)
315  instr(br)(cpu, ic);
316 }
317 
318 
319 /*
320  * br_samepage: Branch (to within the same translated page)
321  *
322  * arg[0] = pointer to new alpha_instr_call
323  */
324 X(br_samepage)
325 {
326  cpu->cd.alpha.next_ic = (struct alpha_instr_call *) ic->arg[0];
327 }
328 
329 
330 /*
331  * br_return_samepage: Branch (to within the same translated page),
332  * and save return address
333  *
334  * arg[0] = pointer to new alpha_instr_call
335  * arg[1] = pointer to uint64_t where to store return address
336  */
337 X(br_return_samepage)
338 {
339  uint64_t low_pc;
340 
341  low_pc = ((size_t)ic - (size_t)
342  cpu->cd.alpha.cur_ic_page) / sizeof(struct alpha_instr_call);
345  cpu->pc += (low_pc << ALPHA_INSTR_ALIGNMENT_SHIFT);
346  *((int64_t *)ic->arg[1]) = cpu->pc + 4;
347 
348  cpu->cd.alpha.next_ic = (struct alpha_instr_call *) ic->arg[0];
349 }
350 
351 
352 /*
353  * beq_samepage: Branch (to within the same translated page) if Equal
354  *
355  * arg[0] = pointer to new alpha_instr_call
356  * arg[1] = pointer to int64_t register
357  */
358 X(beq_samepage)
359 {
360  if (*((int64_t *)ic->arg[1]) == 0)
361  instr(br_samepage)(cpu, ic);
362 }
363 
364 
365 /*
366  * blbs_samepage: Branch (to within the same translated page) if Low Bit Set
367  *
368  * arg[0] = pointer to new alpha_instr_call
369  * arg[1] = pointer to int64_t register
370  */
371 X(blbs_samepage)
372 {
373  if (*((int64_t *)ic->arg[1]) & 1)
374  instr(br_samepage)(cpu, ic);
375 }
376 
377 
378 /*
379  * blbc_samepage: Branch (to within the same translated page) if Low Bit Clear
380  *
381  * arg[0] = pointer to new alpha_instr_call
382  * arg[1] = pointer to int64_t register
383  */
384 X(blbc_samepage)
385 {
386  if (!(*((int64_t *)ic->arg[1]) & 1))
387  instr(br_samepage)(cpu, ic);
388 }
389 
390 
391 /*
392  * bne_samepage: Branch (to within the same translated page) if Not Equal
393  *
394  * arg[0] = pointer to new alpha_instr_call
395  * arg[1] = pointer to int64_t register
396  */
397 X(bne_samepage)
398 {
399  if (*((int64_t *)ic->arg[1]) != 0)
400  instr(br_samepage)(cpu, ic);
401 }
402 
403 
404 /*
405  * ble_samepage: Branch (to within the same translated page) if Less or Equal
406  *
407  * arg[0] = pointer to new alpha_instr_call
408  * arg[1] = pointer to int64_t register
409  */
410 X(ble_samepage)
411 {
412  if (*((int64_t *)ic->arg[1]) <= 0)
413  instr(br_samepage)(cpu, ic);
414 }
415 
416 
417 /*
418  * blt_samepage: Branch (to within the same translated page) if Less Than
419  *
420  * arg[0] = pointer to new alpha_instr_call
421  * arg[1] = pointer to int64_t register
422  */
423 X(blt_samepage)
424 {
425  if (*((int64_t *)ic->arg[1]) < 0)
426  instr(br_samepage)(cpu, ic);
427 }
428 
429 
430 /*
431  * bge_samepage: Branch (to within the same translated page)
432  * if Greater or Equal
433  *
434  * arg[0] = pointer to new alpha_instr_call
435  * arg[1] = pointer to int64_t register
436  */
437 X(bge_samepage)
438 {
439  if (*((int64_t *)ic->arg[1]) >= 0)
440  instr(br_samepage)(cpu, ic);
441 }
442 
443 
444 /*
445  * bgt_samepage: Branch (to within the same translated page) if Greater Than
446  *
447  * arg[0] = pointer to new alpha_instr_call
448  * arg[1] = pointer to int64_t register
449  */
450 X(bgt_samepage)
451 {
452  if (*((int64_t *)ic->arg[1]) > 0)
453  instr(br_samepage)(cpu, ic);
454 }
455 
456 
457 /*
458  * cvttq/c: Convert floating point to quad.
459  *
460  * arg[0] = pointer to rc (destination integer)
461  * arg[2] = pointer to rb (source float)
462  */
463 X(cvttq_c)
464 {
465  struct ieee_float_value fb;
467  reg(ic->arg[0]) = fb.nan? 0 : fb.f;
468 }
469 
470 
471 /*
472  * cvtqt: Convert quad to floating point.
473  *
474  * arg[0] = pointer to rc (destination float)
475  * arg[2] = pointer to rb (source quad integer)
476  */
477 X(cvtqt)
478 {
479  reg(ic->arg[0]) = ieee_store_float_value(reg(ic->arg[2]), IEEE_FMT_D);
480 }
481 
482 
483 /*
484  * fabs, fneg: Floating point absolute value, or negation.
485  *
486  * arg[0] = pointer to rc (destination float)
487  * arg[2] = pointer to rb (source quad integer)
488  */
489 X(fabs)
490 {
491  reg(ic->arg[0]) = reg(ic->arg[2]) & 0x7fffffffffffffffULL;
492 }
493 X(fneg)
494 {
495  reg(ic->arg[0]) = reg(ic->arg[2]) ^ 0x8000000000000000ULL;
496 }
497 
498 
499 /*
500  * addt, subt, mult, divt: Floating point arithmetic.
501  *
502  * arg[0] = pointer to rc (destination)
503  * arg[1] = pointer to ra (source)
504  * arg[2] = pointer to rb (source)
505  */
506 X(addt)
507 {
508  struct ieee_float_value fa, fb;
511  reg(ic->arg[0]) = ieee_store_float_value(fa.f + fb.f, IEEE_FMT_D);
512 }
513 X(subt)
514 {
515  struct ieee_float_value fa, fb;
518  reg(ic->arg[0]) = ieee_store_float_value(fa.f - fb.f, IEEE_FMT_D);
519 }
520 X(mult)
521 {
522  struct ieee_float_value fa, fb;
525  reg(ic->arg[0]) = ieee_store_float_value(fa.f * fb.f, IEEE_FMT_D);
526 }
527 X(divt)
528 {
529  struct ieee_float_value fa, fb;
532  reg(ic->arg[0]) = ieee_store_float_value(fa.f / fb.f, IEEE_FMT_D);
533 }
534 X(cmpteq)
535 {
536  struct ieee_float_value fa, fb;
537  int res = 0;
540  if (fa.nan | fb.nan)
541  res = 0;
542  else
543  res = fa.f == fb.f;
544  reg(ic->arg[0]) = res;
545 }
546 X(cmptlt)
547 {
548  struct ieee_float_value fa, fb;
549  int res = 0;
552  if (fa.nan | fb.nan)
553  res = 0;
554  else
555  res = fa.f < fb.f;
556  reg(ic->arg[0]) = res;
557 }
558 X(cmptle)
559 {
560  struct ieee_float_value fa, fb;
561  int res = 0;
564  if (fa.nan | fb.nan)
565  res = 0;
566  else
567  res = fa.f <= fb.f;
568  reg(ic->arg[0]) = res;
569 }
570 
571 
572 /*
573  * implver: Return CPU implver value.
574  *
575  * arg[0] = pointer to destination uint64_t
576  */
577 X(implver)
578 {
579  reg(ic->arg[0]) = cpu->cd.alpha.cpu_type.implver;
580 }
581 
582 
583 /*
584  * mull, mull_imm: Signed Multiply 32x32 => 32.
585  *
586  * arg[0] = pointer to destination uint64_t
587  * arg[1] = pointer to source uint64_t
588  * arg[2] = pointer to source uint64_t or immediate
589  */
590 X(mull)
591 {
592  int32_t a = reg(ic->arg[1]);
593  int32_t b = reg(ic->arg[2]);
594  reg(ic->arg[0]) = (int64_t)(int32_t)(a * b);
595 }
596 X(mull_imm)
597 {
598  int32_t a = reg(ic->arg[1]);
599  int32_t b = ic->arg[2];
600  reg(ic->arg[0]) = (int64_t)(int32_t)(a * b);
601 }
602 
603 
604 /*
605  * mulq, mulq_imm: Unsigned Multiply 64x64 => 64.
606  *
607  * arg[0] = pointer to destination uint64_t
608  * arg[1] = pointer to source uint64_t
609  * arg[2] = pointer to source uint64_t or immediate
610  */
611 X(mulq)
612 {
613  reg(ic->arg[0]) = reg(ic->arg[1]) * reg(ic->arg[2]);
614 }
615 X(mulq_imm)
616 {
617  reg(ic->arg[0]) = reg(ic->arg[1]) * ic->arg[2];
618 }
619 
620 
621 /*
622  * umulh: Unsigned Multiply 64x64 => 128. Store high part in dest reg.
623  *
624  * arg[0] = pointer to destination uint64_t
625  * arg[1] = pointer to source uint64_t
626  * arg[2] = pointer to source uint64_t
627  */
628 X(umulh)
629 {
630  uint64_t reshi = 0, reslo = 0;
631  uint64_t s1 = reg(ic->arg[1]), s2 = reg(ic->arg[2]);
632  int i, bit;
633 
634  for (i=0; i<64; i++) {
635  bit = (s1 & 0x8000000000000000ULL)? 1 : 0;
636  s1 <<= 1;
637 
638  /* If bit in s1 set, then add s2 to reshi/lo: */
639  if (bit) {
640  uint64_t old_reslo = reslo;
641  reslo += s2;
642  if (reslo < old_reslo)
643  reshi ++;
644  }
645 
646  if (i != 63) {
647  reshi <<= 1;
648  reshi += (reslo & 0x8000000000000000ULL? 1 : 0);
649  reslo <<= 1;
650  }
651  }
652 
653  reg(ic->arg[0]) = reshi;
654 }
655 
656 
657 /*
658  * lda: Load address.
659  *
660  * arg[0] = pointer to destination uint64_t
661  * arg[1] = pointer to source uint64_t
662  * arg[2] = offset (possibly as an int32_t)
663  */
664 X(lda)
665 {
666  reg(ic->arg[0]) = reg(ic->arg[1]) + (int64_t)(int32_t)ic->arg[2];
667 }
668 
669 
670 /*
671  * lda_0: Load address compared to the zero register.
672  *
673  * arg[0] = pointer to destination uint64_t
674  * arg[1] = ignored
675  * arg[2] = offset (possibly as an int32_t)
676  */
677 X(lda_0)
678 {
679  reg(ic->arg[0]) = (int64_t)(int32_t)ic->arg[2];
680 }
681 
682 
683 /*
684  * clear: Clear a 64-bit register.
685  *
686  * arg[0] = pointer to destination uint64_t
687  */
688 X(clear)
689 {
690  reg(ic->arg[0]) = 0;
691 }
692 
693 
694 /*
695  * rdcc: Read the Cycle Counter into a 64-bit register.
696  *
697  * arg[0] = pointer to destination uint64_t
698  */
699 X(rdcc)
700 {
701  reg(ic->arg[0]) = cpu->cd.alpha.pcc;
702 
703  /* TODO: actually keep the pcc updated! */
704  cpu->cd.alpha.pcc += 20;
705 }
706 
707 
708 #include "tmp_alpha_misc.cc"
709 
710 
711 /*****************************************************************************/
712 
713 
714 X(end_of_page)
715 {
716  /* Update the PC: (offset 0, but on the next page) */
721 
722  /* Find the new physical page and update the translation pointers: */
723  alpha_pc_to_pointers(cpu);
724 
725  /* end_of_page doesn't count as an executed instruction: */
727 }
728 
729 
730 /*****************************************************************************/
731 
732 
733 /*
734  * alpha_instr_to_be_translated():
735  *
736  * Translate an instruction word into an alpha_instr_call. ic is filled in with
737  * valid data for the translated instruction, or a "nothing" instruction if
738  * there was a translation failure. The newly translated instruction is then
739  * executed.
740  */
741 X(to_be_translated)
742 {
743  uint64_t addr, low_pc;
744  uint32_t iword;
745  unsigned char *page;
746  unsigned char ib[4];
747  void (*samepage_function)(struct cpu *, struct alpha_instr_call *);
748  int opcode, ra, rb, func, rc, imm, load, loadstore_type, fp, llsc;
749 
750  /* Figure out the (virtual) address of the instruction: */
751  low_pc = ((size_t)ic - (size_t)cpu->cd.alpha.cur_ic_page)
752  / sizeof(struct alpha_instr_call);
753  addr = cpu->pc & ~((ALPHA_IC_ENTRIES_PER_PAGE-1) <<
755  addr += (low_pc << ALPHA_INSTR_ALIGNMENT_SHIFT);
756  addr &= ~((1 << ALPHA_INSTR_ALIGNMENT_SHIFT) - 1);
757  cpu->pc = addr;
758 
759  /* Read the instruction word from memory: */
760  {
761  const uint32_t mask1 = (1 << DYNTRANS_L1N) - 1;
762  const uint32_t mask2 = (1 << DYNTRANS_L2N) - 1;
763  const uint32_t mask3 = (1 << DYNTRANS_L3N) - 1;
764  uint32_t x1 = (addr >> (64-DYNTRANS_L1N)) & mask1;
765  uint32_t x2 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2;
766  uint32_t x3 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N-
767  DYNTRANS_L3N)) & mask3;
768  struct DYNTRANS_L2_64_TABLE *l2 = cpu->cd.alpha.l1_64[x1];
769  struct DYNTRANS_L3_64_TABLE *l3 = l2->l3[x2];
770  page = l3->host_load[x3];
771  }
772 
773  if (page != NULL) {
774  /* fatal("TRANSLATION HIT!\n"); */
775  memcpy(ib, page + (addr & 8191), sizeof(ib));
776  } else {
777  /* fatal("TRANSLATION MISS!\n"); */
778  if (!cpu->memory_rw(cpu, cpu->mem, addr, &ib[0],
779  sizeof(ib), MEM_READ, CACHE_INSTRUCTION)) {
780  fatal("to_be_translated(): read failed: TODO\n");
781  goto bad;
782  }
783  }
784 
785  /* Alpha instruction words are always little-endian. Convert
786  to host order: */
787  {
788  uint32_t *p = (uint32_t *) ib;
789  iword = LE32_TO_HOST( *p );
790  }
791 
792 #define DYNTRANS_TO_BE_TRANSLATED_HEAD
793 #include "cpu_dyntrans.cc"
794 #undef DYNTRANS_TO_BE_TRANSLATED_HEAD
795 
796 
797  opcode = (iword >> 26) & 63;
798  ra = (iword >> 21) & 31;
799  rb = (iword >> 16) & 31;
800  func = (iword >> 5) & 0x7ff;
801  rc = iword & 31;
802  imm = iword & 0xffff;
803 
804  switch (opcode) {
805  case 0x00: /* CALL_PAL */
806  ic->f = instr(call_pal);
807  ic->arg[0] = (size_t) (iword & 0x3ffffff);
808  break;
809  case 0x08: /* LDA */
810  case 0x09: /* LDAH */
811  if (ra == ALPHA_ZERO) {
812  ic->f = instr(nop);
813  break;
814  }
815  /* TODO: A special case which is common is to add or subtract
816  a small offset from sp. */
817  ic->f = instr(lda);
818  ic->arg[0] = (size_t) &cpu->cd.alpha.r[ra];
819  ic->arg[1] = (size_t) &cpu->cd.alpha.r[rb];
820  if (rb == ALPHA_ZERO)
821  ic->f = instr(lda_0);
822  ic->arg[2] = (ssize_t)(int16_t)imm;
823  if (opcode == 0x09)
824  ic->arg[2] <<= 16;
825  break;
826  case 0x0b: /* LDQ_U */
827  case 0x0f: /* STQ_U */
828  if (ra == ALPHA_ZERO && opcode == 0x0b) {
829  ic->f = instr(nop);
830  break;
831  }
832  if (opcode == 0x0b)
833  ic->f = instr(ldq_u);
834  else
835  ic->f = instr(stq_u);
836  ic->arg[0] = (size_t) &cpu->cd.alpha.r[ra];
837  ic->arg[1] = (size_t) &cpu->cd.alpha.r[rb];
838  ic->arg[2] = (ssize_t)(int16_t)imm;
839  break;
840  case 0x0a:
841  case 0x0c:
842  case 0x0d:
843  case 0x0e:
844  case 0x22:
845  case 0x23:
846  case 0x26:
847  case 0x27:
848  case 0x28:
849  case 0x29:
850  case 0x2a:
851  case 0x2b:
852  case 0x2c:
853  case 0x2d:
854  case 0x2e:
855  case 0x2f:
856  loadstore_type = 0; fp = 0; load = 0; llsc = 0;
857  switch (opcode) {
858  case 0x0a: loadstore_type = 0; load = 1; break; /* ldbu */
859  case 0x0c: loadstore_type = 1; load = 1; break; /* ldwu */
860  case 0x0d: loadstore_type = 1; break; /* stw */
861  case 0x0e: loadstore_type = 0; break; /* stb */
862  case 0x22: loadstore_type = 2; load = 1; fp = 1; break; /*lds*/
863  case 0x23: loadstore_type = 3; load = 1; fp = 1; break; /*ldt*/
864  case 0x26: loadstore_type = 2; fp = 1; break; /* sts */
865  case 0x27: loadstore_type = 3; fp = 1; break; /* stt */
866  case 0x28: loadstore_type = 2; load = 1; break; /* ldl */
867  case 0x29: loadstore_type = 3; load = 1; break; /* ldq */
868  case 0x2a: loadstore_type = 2; load = llsc = 1; break;/* ldl_l*/
869  case 0x2b: loadstore_type = 3; load = llsc = 1; break;/* ldq_l*/
870  case 0x2c: loadstore_type = 2; break; /* stl */
871  case 0x2d: loadstore_type = 3; break; /* stq */
872  case 0x2e: loadstore_type = 2; llsc = 1; break; /* stl_c */
873  case 0x2f: loadstore_type = 3; llsc = 1; break; /* stq_c */
874  }
875  ic->f = alpha_loadstore[
876  loadstore_type + (imm==0? 4 : 0) + 8 * load
877  + 16 * llsc];
878  /* Load to the zero register is treated as a prefetch
879  hint. It is ignored here. */
880  if (load && ra == ALPHA_ZERO) {
881  ic->f = instr(nop);
882  break;
883  }
884  if (fp)
885  ic->arg[0] = (size_t) &cpu->cd.alpha.f[ra];
886  else
887  ic->arg[0] = (size_t) &cpu->cd.alpha.r[ra];
888  ic->arg[1] = (size_t) &cpu->cd.alpha.r[rb];
889  ic->arg[2] = (ssize_t)(int16_t)imm;
890  break;
891  case 0x10:
892  if (rc == ALPHA_ZERO) {
893  ic->f = instr(nop);
894  break;
895  }
896  ic->arg[0] = (size_t) &cpu->cd.alpha.r[rc];
897  ic->arg[1] = (size_t) &cpu->cd.alpha.r[ra];
898  if (func & 0x80)
899  ic->arg[2] = (size_t)((rb << 3) + (func >> 8));
900  else
901  ic->arg[2] = (size_t) &cpu->cd.alpha.r[rb];
902  switch (func & 0xff) {
903  case 0x00: ic->f = instr(addl); break;
904  case 0x02: ic->f = instr(s4addl); break;
905  case 0x09: ic->f = instr(subl); break;
906  case 0x0b: ic->f = instr(s4subl); break;
907  case 0x0f: ic->f = instr(cmpbge); break;
908  case 0x12: ic->f = instr(s8addl); break;
909  case 0x1b: ic->f = instr(s8subl); break;
910  case 0x1d: ic->f = instr(cmpult); break;
911  case 0x20: ic->f = instr(addq); break;
912  case 0x22: ic->f = instr(s4addq); break;
913  case 0x29: ic->f = instr(subq); break;
914  case 0x2b: ic->f = instr(s4subq); break;
915  case 0x2d: ic->f = instr(cmpeq); break;
916  case 0x32: ic->f = instr(s8addq); break;
917  case 0x3b: ic->f = instr(s8subq); break;
918  case 0x3d: ic->f = instr(cmpule); break;
919  case 0x4d: ic->f = instr(cmplt); break;
920  // case 0x69: ic->f = instr(subq_v); break;
921  case 0x6d: ic->f = instr(cmple); break;
922 
923  case 0x80: ic->f = instr(addl_imm); break;
924  case 0x82: ic->f = instr(s4addl_imm); break;
925  case 0x89: ic->f = instr(subl_imm); break;
926  case 0x8b: ic->f = instr(s4subl_imm); break;
927  case 0x8f: ic->f = instr(cmpbge_imm); break;
928  case 0x92: ic->f = instr(s8addl_imm); break;
929  case 0x9b: ic->f = instr(s8subl_imm); break;
930  case 0x9d: ic->f = instr(cmpult_imm); break;
931  case 0xa0: ic->f = instr(addq_imm); break;
932  case 0xa2: ic->f = instr(s4addq_imm); break;
933  case 0xa9: ic->f = instr(subq_imm); break;
934  case 0xab: ic->f = instr(s4subq_imm); break;
935  case 0xad: ic->f = instr(cmpeq_imm); break;
936  case 0xb2: ic->f = instr(s8addq_imm); break;
937  case 0xbb: ic->f = instr(s8subq_imm); break;
938  case 0xbd: ic->f = instr(cmpule_imm); break;
939  case 0xcd: ic->f = instr(cmplt_imm); break;
940  case 0xed: ic->f = instr(cmple_imm); break;
941 
942  default:if (!cpu->translation_readahead)
943  fatal("[ Alpha: unimplemented function 0x%03x "
944  "for opcode 0x%02x ]\n", func, opcode);
945  goto bad;
946  }
947  break;
948  case 0x11:
949  if (rc == ALPHA_ZERO) {
950  ic->f = instr(nop);
951  break;
952  }
953  ic->arg[0] = (size_t) &cpu->cd.alpha.r[rc];
954  ic->arg[1] = (size_t) &cpu->cd.alpha.r[ra];
955  if (func & 0x80)
956  ic->arg[2] = (size_t)((rb << 3) + (func >> 8));
957  else
958  ic->arg[2] = (size_t) &cpu->cd.alpha.r[rb];
959  switch (func & 0xff) {
960  case 0x00: ic->f = instr(and); break;
961  case 0x08: ic->f = instr(andnot); break;
962  case 0x14: ic->f = instr(cmovlbs); break;
963  case 0x16: ic->f = instr(cmovlbc); break;
964  case 0x20: ic->f = instr(or);
965  if (ra == ALPHA_ZERO || rb == ALPHA_ZERO) {
966  if (ra == ALPHA_ZERO)
967  ra = rb;
968  ic->f = alpha_mov_r_r[ra + rc*32];
969  }
970  break;
971  case 0x24: ic->f = instr(cmoveq); break;
972  case 0x26: ic->f = instr(cmovne); break;
973  case 0x28: ic->f = instr(ornot); break;
974  case 0x40: ic->f = instr(xor); break;
975  case 0x44: ic->f = instr(cmovlt); break;
976  case 0x46: ic->f = instr(cmovge); break;
977  case 0x48: ic->f = instr(xornot); break;
978  case 0x64: ic->f = instr(cmovle); break;
979  case 0x66: ic->f = instr(cmovgt); break;
980  case 0x80: ic->f = instr(and_imm); break;
981  case 0x88: ic->f = instr(andnot_imm); break;
982  case 0x94: ic->f = instr(cmovlbs_imm); break;
983  case 0x96: ic->f = instr(cmovlbc_imm); break;
984  case 0xa0: ic->f = instr(or_imm); break;
985  case 0xa4: ic->f = instr(cmoveq_imm); break;
986  case 0xa6: ic->f = instr(cmovne_imm); break;
987  case 0xa8: ic->f = instr(ornot_imm); break;
988  case 0xc0: ic->f = instr(xor_imm); break;
989  case 0xc4: ic->f = instr(cmovlt_imm); break;
990  case 0xc6: ic->f = instr(cmovge_imm); break;
991  case 0xc8: ic->f = instr(xornot_imm); break;
992  case 0xe4: ic->f = instr(cmovle_imm); break;
993  case 0xe6: ic->f = instr(cmovgt_imm); break;
994  case 0xec: ic->f = instr(implver); break;
995  default:if (!cpu->translation_readahead)
996  fatal("[ Alpha: unimplemented function 0x%03x "
997  "for opcode 0x%02x ]\n", func, opcode);
998  goto bad;
999  }
1000  break;
1001  case 0x12:
1002  if (rc == ALPHA_ZERO) {
1003  ic->f = instr(nop);
1004  break;
1005  }
1006  ic->arg[0] = (size_t) &cpu->cd.alpha.r[rc];
1007  ic->arg[1] = (size_t) &cpu->cd.alpha.r[ra];
1008  if (func & 0x80)
1009  ic->arg[2] = (size_t)((rb << 3) + (func >> 8));
1010  else
1011  ic->arg[2] = (size_t) &cpu->cd.alpha.r[rb];
1012  switch (func & 0xff) {
1013  case 0x02: ic->f = instr(mskbl); break;
1014  case 0x06: ic->f = instr(extbl); break;
1015  case 0x0b: ic->f = instr(insbl); break;
1016  case 0x12: ic->f = instr(mskwl); break;
1017  case 0x16: ic->f = instr(extwl); break;
1018  case 0x1b: ic->f = instr(inswl); break;
1019  case 0x22: ic->f = instr(mskll); break;
1020  case 0x26: ic->f = instr(extll); break;
1021  case 0x2b: ic->f = instr(insll); break;
1022  case 0x30: ic->f = instr(zap); break;
1023  case 0x31: ic->f = instr(zapnot); break;
1024  case 0x32: ic->f = instr(mskql); break;
1025  case 0x34: ic->f = instr(srl); break;
1026  case 0x36: ic->f = instr(extql); break;
1027  case 0x39: ic->f = instr(sll); break;
1028  case 0x3b: ic->f = instr(insql); break;
1029  case 0x3c: ic->f = instr(sra); break;
1030  case 0x52: ic->f = instr(mskwh); break;
1031  case 0x57: ic->f = instr(inswh); break;
1032  case 0x5a: ic->f = instr(extwh); break;
1033  case 0x62: ic->f = instr(msklh); break;
1034  case 0x67: ic->f = instr(inslh); break;
1035  case 0x6a: ic->f = instr(extlh); break;
1036  case 0x72: ic->f = instr(mskqh); break;
1037  case 0x77: ic->f = instr(insqh); break;
1038  case 0x7a: ic->f = instr(extqh); break;
1039  case 0x82: ic->f = instr(mskbl_imm); break;
1040  case 0x86: ic->f = instr(extbl_imm); break;
1041  case 0x8b: ic->f = instr(insbl_imm); break;
1042  case 0x92: ic->f = instr(mskwl_imm); break;
1043  case 0x96: ic->f = instr(extwl_imm); break;
1044  case 0x9b: ic->f = instr(inswl_imm); break;
1045  case 0xa2: ic->f = instr(mskll_imm); break;
1046  case 0xa6: ic->f = instr(extll_imm); break;
1047  case 0xab: ic->f = instr(insll_imm); break;
1048  case 0xb0: ic->f = instr(zap_imm); break;
1049  case 0xb1: ic->f = instr(zapnot_imm); break;
1050  case 0xb2: ic->f = instr(mskql_imm); break;
1051  case 0xb4: ic->f = instr(srl_imm); break;
1052  case 0xb6: ic->f = instr(extql_imm); break;
1053  case 0xb9: ic->f = instr(sll_imm); break;
1054  case 0xbb: ic->f = instr(insql_imm); break;
1055  case 0xbc: ic->f = instr(sra_imm); break;
1056  case 0xd2: ic->f = instr(mskwh_imm); break;
1057  case 0xd7: ic->f = instr(inswh_imm); break;
1058  case 0xda: ic->f = instr(extwh_imm); break;
1059  case 0xe2: ic->f = instr(msklh_imm); break;
1060  case 0xe7: ic->f = instr(inslh_imm); break;
1061  case 0xea: ic->f = instr(extlh_imm); break;
1062  case 0xf2: ic->f = instr(mskqh_imm); break;
1063  case 0xf7: ic->f = instr(insqh_imm); break;
1064  case 0xfa: ic->f = instr(extqh_imm); break;
1065  default:if (!cpu->translation_readahead)
1066  fatal("[ Alpha: unimplemented function 0x%03x "
1067  "for opcode 0x%02x ]\n", func, opcode);
1068  goto bad;
1069  }
1070  break;
1071  case 0x13:
1072  if (rc == ALPHA_ZERO) {
1073  ic->f = instr(nop);
1074  break;
1075  }
1076  ic->arg[0] = (size_t) &cpu->cd.alpha.r[rc];
1077  ic->arg[1] = (size_t) &cpu->cd.alpha.r[ra];
1078  if (func & 0x80)
1079  ic->arg[2] = (size_t)((rb << 3) + (func >> 8));
1080  else
1081  ic->arg[2] = (size_t) &cpu->cd.alpha.r[rb];
1082  // TODO: mulq/v etc? overflow detection
1083  // bit 0..6 are function, but 7 is "imm" bit.
1084  switch (func & 0xff) {
1085  case 0x00: ic->f = instr(mull); break;
1086  case 0x20: ic->f = instr(mulq); break;
1087  case 0x30: ic->f = instr(umulh); break;
1088  case 0x80: ic->f = instr(mull_imm); break;
1089  case 0xa0: ic->f = instr(mulq_imm); break;
1090  default:if (!cpu->translation_readahead)
1091  fatal("[ Alpha: unimplemented function 0x%03x "
1092  "for opcode 0x%02x ]\n", func, opcode);
1093  goto bad;
1094  }
1095  break;
1096  case 0x16:
1097  if (rc == ALPHA_ZERO) {
1098  ic->f = instr(nop);
1099  break;
1100  }
1101  ic->arg[0] = (size_t) &cpu->cd.alpha.f[rc];
1102  ic->arg[1] = (size_t) &cpu->cd.alpha.f[ra];
1103  ic->arg[2] = (size_t) &cpu->cd.alpha.f[rb];
1104  switch (func & 0x7ff) {
1105  case 0x02f: ic->f = instr(cvttq_c); break;
1106  case 0x0a0: ic->f = instr(addt); break;
1107  case 0x0a1: ic->f = instr(subt); break;
1108  case 0x0a2: ic->f = instr(mult); break;
1109  case 0x0a3: ic->f = instr(divt); break;
1110  case 0x0a5: ic->f = instr(cmpteq); break;
1111  case 0x0a6: ic->f = instr(cmptlt); break;
1112  case 0x0a7: ic->f = instr(cmptle); break;
1113  case 0x0be: ic->f = instr(cvtqt); break;
1114  default:if (!cpu->translation_readahead)
1115  fatal("[ Alpha: unimplemented function 0x%03x "
1116  "for opcode 0x%02x ]\n", func, opcode);
1117  goto bad;
1118  }
1119  break;
1120  case 0x17:
1121  if (rc == ALPHA_ZERO) {
1122  ic->f = instr(nop);
1123  break;
1124  }
1125  ic->arg[0] = (size_t) &cpu->cd.alpha.f[rc];
1126  ic->arg[1] = (size_t) &cpu->cd.alpha.f[ra];
1127  ic->arg[2] = (size_t) &cpu->cd.alpha.f[rb];
1128  switch (func & 0x7ff) {
1129  case 0x020:
1130  /* fabs (or fclr): */
1131  if (ra == 31 && rb == 31)
1132  ic->f = instr(clear);
1133  else
1134  ic->f = instr(fabs);
1135  break;
1136  case 0x021:
1137  ic->f = instr(fneg);
1138  break;
1139  default:if (!cpu->translation_readahead)
1140  fatal("[ Alpha: unimplemented function 0x%03x "
1141  "for opcode 0x%02x ]\n", func, opcode);
1142  goto bad;
1143  }
1144  break;
1145  case 0x18:
1146  switch (iword & 0xffff) {
1147  case 0x4000: /* mb */
1148  case 0x4400: /* wmb */
1149  ic->f = instr(nop);
1150  break;
1151  case 0xc000: /* rdcc ra */
1152  if (ra == ALPHA_ZERO) {
1153  ic->f = instr(nop);
1154  break;
1155  }
1156  ic->arg[0] = (size_t) &cpu->cd.alpha.r[ra];
1157  ic->f = instr(rdcc);
1158  break;
1159  default:if (!cpu->translation_readahead)
1160  fatal("[ Alpha: unimplemented function 0x%03x "
1161  "for opcode 0x%02x ]\n", func, opcode);
1162  goto bad;
1163  }
1164  break;
1165  case 0x1a:
1166  switch ((iword >> 14) & 3) {
1167  case 0: /* JMP */
1168  case 1: /* JSR */
1169  case 2: /* RET */
1170  ic->arg[0] = (size_t) &cpu->cd.alpha.r[ra];
1171  ic->arg[1] = (size_t) &cpu->cd.alpha.r[rb];
1172  if (ra == ALPHA_ZERO) {
1173  if (cpu->machine->show_trace_tree &&
1174  rb == ALPHA_RA)
1175  ic->f = instr(jsr_0_trace);
1176  else
1177  ic->f = instr(jsr_0);
1178  } else {
1179  if (cpu->machine->show_trace_tree)
1180  ic->f = instr(jsr_trace);
1181  else
1182  ic->f = instr(jsr);
1183  }
1184  break;
1185  default:if (!cpu->translation_readahead)
1186  fatal("[ Alpha: unimpl JSR type %i, ra=%i "
1187  "rb=%i ]\n", ((iword >> 14) & 3), ra, rb);
1188  goto bad;
1189  }
1190  break;
1191  case 0x30: /* BR */
1192  case 0x31: /* FBEQ */
1193  case 0x34: /* BSR */
1194  case 0x35: /* FBNE */
1195  case 0x38: /* BLBC */
1196  case 0x39: /* BEQ */
1197  case 0x3a: /* BLT */
1198  case 0x3b: /* BLE */
1199  case 0x3c: /* BLBS */
1200  case 0x3d: /* BNE */
1201  case 0x3e: /* BGE */
1202  case 0x3f: /* BGT */
1203  /* To avoid a GCC warning: */
1204  samepage_function = instr(nop);
1205  fp = 0;
1206  switch (opcode) {
1207  case 0x30:
1208  case 0x34:
1209  ic->f = instr(br);
1210  samepage_function = instr(br_samepage);
1211  if (ra != ALPHA_ZERO) {
1212  ic->f = instr(br_return);
1213  samepage_function = instr(br_return_samepage);
1214  }
1215  break;
1216  case 0x38:
1217  ic->f = instr(blbc);
1218  samepage_function = instr(blbc_samepage);
1219  break;
1220  case 0x31:
1221  fp = 1;
1222  case 0x39:
1223  ic->f = instr(beq);
1224  samepage_function = instr(beq_samepage);
1225  break;
1226  case 0x3a:
1227  ic->f = instr(blt);
1228  samepage_function = instr(blt_samepage);
1229  break;
1230  case 0x3b:
1231  ic->f = instr(ble);
1232  samepage_function = instr(ble_samepage);
1233  break;
1234  case 0x3c:
1235  ic->f = instr(blbs);
1236  samepage_function = instr(blbs_samepage);
1237  break;
1238  case 0x35:
1239  fp = 1;
1240  case 0x3d:
1241  ic->f = instr(bne);
1242  samepage_function = instr(bne_samepage);
1243  break;
1244  case 0x3e:
1245  ic->f = instr(bge);
1246  samepage_function = instr(bge_samepage);
1247  break;
1248  case 0x3f:
1249  ic->f = instr(bgt);
1250  samepage_function = instr(bgt_samepage);
1251  break;
1252  }
1253  if (fp)
1254  ic->arg[1] = (size_t) &cpu->cd.alpha.f[ra];
1255  else
1256  ic->arg[1] = (size_t) &cpu->cd.alpha.r[ra];
1257  ic->arg[0] = (iword & 0x001fffff) << 2;
1258  /* Sign-extend: */
1259  if (ic->arg[0] & 0x00400000)
1260  ic->arg[0] |= 0xffffffffff800000ULL;
1261  /* Branches are calculated as PC + 4 + offset. */
1262  ic->arg[0] = (size_t)(ic->arg[0] + 4);
1263  /* Special case: branch within the same page: */
1264  {
1265  uint64_t mask_within_page =
1266  ((ALPHA_IC_ENTRIES_PER_PAGE-1) << 2) | 3;
1267  uint64_t old_pc = addr;
1268  uint64_t new_pc = old_pc + (int32_t)ic->arg[0];
1269  if ((old_pc & ~mask_within_page) ==
1270  (new_pc & ~mask_within_page)) {
1271  ic->f = samepage_function;
1272  ic->arg[0] = (size_t) (
1273  cpu->cd.alpha.cur_ic_page +
1274  ((new_pc & mask_within_page) >> 2));
1275  }
1276  }
1277  break;
1278  default:if (!cpu->translation_readahead)
1279  fatal("[ UNIMPLEMENTED Alpha opcode 0x%x ]\n", opcode);
1280  goto bad;
1281  }
1282 
1283 
1284 #define DYNTRANS_TO_BE_TRANSLATED_TAIL
1285 #include "cpu_dyntrans.cc"
1286 #undef DYNTRANS_TO_BE_TRANSLATED_TAIL
1287 }
1288 
ALPHA_INSTR_ALIGNMENT_SHIFT
#define ALPHA_INSTR_ALIGNMENT_SHIFT
Definition: cpu_alpha.h:123
instr
#define instr(n)
Definition: tmp_alpha_head.cc:43
alpha_cpu::f
uint64_t f[N_ALPHA_REGS]
Definition: cpu_alpha.h:152
cpu_dyntrans.cc
alpha_loadstore
void(* alpha_loadstore[32])(struct cpu *, struct alpha_instr_call *)
Definition: tmp_alpha_misc.cc:1166
cpu::running
uint8_t running
Definition: cpu.h:353
cpu_functioncall_trace_return
void cpu_functioncall_trace_return(struct cpu *cpu)
Definition: cpu.cc:284
cpu::n_translated_instrs
int n_translated_instrs
Definition: cpu.h:430
machine::show_trace_tree
int show_trace_tree
Definition: machine.h:164
if
addr & if(addr >=0x24 &&page !=NULL)
Definition: tmp_arm_multi.cc:56
ieee_interpret_float_value
void ieee_interpret_float_value(uint64_t x, struct ieee_float_value *fvp, int fmt)
Definition: float_emul.cc:49
DYNTRANS_L1N
#define DYNTRANS_L1N
Definition: cpu.h:222
cpu::alpha
struct alpha_cpu alpha
Definition: cpu.h:443
MEM_READ
#define MEM_READ
Definition: memory.h:116
alpha_mov_r_r
void(* alpha_mov_r_r[32 *31])(struct cpu *, struct alpha_instr_call *)
Definition: tmp_alpha_misc.cc:3125
cpu_functioncall_trace
void cpu_functioncall_trace(struct cpu *cpu, uint64_t f)
Definition: cpu.cc:228
LE32_TO_HOST
#define LE32_TO_HOST(x)
Definition: misc.h:180
addr
uint32_t addr
Definition: tmp_arm_multi.cc:52
IEEE_FMT_D
#define IEEE_FMT_D
Definition: float_emul.h:44
X
X(nop)
Definition: cpu_alpha_instr.cc:43
ALPHA_ZERO
#define ALPHA_ZERO
Definition: cpu_alpha.h:109
ieee_store_float_value
uint64_t ieee_store_float_value(double nf, int fmt)
Definition: float_emul.cc:238
fatal
void fatal(const char *fmt,...)
Definition: main.cc:152
ALPHA_IC_ENTRIES_PER_PAGE
#define ALPHA_IC_ENTRIES_PER_PAGE
Definition: cpu_alpha.h:125
ieee_float_value::nan
int nan
Definition: float_emul.h:40
cpu::cd
union cpu::@1 cd
page
page
Definition: tmp_arm_multi.cc:54
ic
struct arm_instr_call * ic
Definition: tmp_arm_multi.cc:50
CACHE_INSTRUCTION
#define CACHE_INSTRUCTION
Definition: memory.h:122
alpha_palcode
void alpha_palcode(struct cpu *cpu, uint32_t palcode)
Definition: cpu_alpha_palcode.cc:163
alpha_cpu::r
uint64_t r[N_ALPHA_REGS]
Definition: cpu_alpha.h:151
ieee_float_value
Definition: float_emul.h:38
alpha_cpu::cpu_type
struct alpha_cpu_type_def cpu_type
Definition: cpu_alpha.h:144
float_emul.h
DYNTRANS_L2N
#define DYNTRANS_L2N
Definition: tmp_alpha_head.cc:10
cpu::mem
struct memory * mem
Definition: cpu.h:362
DYNTRANS_L3N
#define DYNTRANS_L3N
Definition: tmp_alpha_head.cc:11
ieee_float_value::f
double f
Definition: float_emul.h:39
cpu::machine
struct machine * machine
Definition: cpu.h:328
reg
#define reg(x)
Definition: tmp_alpha_tail.cc:53
tmp_alpha_misc.cc
nop
void COMBINE() nop(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
Definition: cpu_mips_instr.cc:3365
DYNTRANS_L3_64_TABLE
#define DYNTRANS_L3_64_TABLE
Definition: tmp_alpha_head.cc:16
alpha_cpu_type_def::implver
int implver
Definition: cpu_alpha.h:44
cpu::translation_readahead
int translation_readahead
Definition: cpu.h:427
cpu
Definition: cpu.h:326
sll
void COMBINE() sll(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
Definition: cpu_mips_instr.cc:3439
DYNTRANS_L2_64_TABLE
#define DYNTRANS_L2_64_TABLE
Definition: tmp_alpha_head.cc:15
cpu::memory_rw
int(* memory_rw)(struct cpu *cpu, struct memory *mem, uint64_t vaddr, unsigned char *data, size_t len, int writeflag, int cache_flags)
Definition: cpu.h:368
load
void load(FILE *fh, unsigned char *ptr, unsigned long sz)
Definition: dreamcast_scramble.cc:33
cpu::pc
uint64_t pc
Definition: cpu.h:386
alpha_cpu::pcc
uint64_t pcc
Definition: cpu_alpha.h:157
ALPHA_RA
#define ALPHA_RA
Definition: cpu_alpha.h:104

Generated on Tue Aug 25 2020 19:25:06 for GXemul by doxygen 1.8.18