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-2011 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]),
480  IEEE_FMT_D, 0);
481 }
482 
483 
484 /*
485  * fabs, fneg: Floating point absolute value, or negation.
486  *
487  * arg[0] = pointer to rc (destination float)
488  * arg[2] = pointer to rb (source quad integer)
489  */
490 X(fabs)
491 {
492  reg(ic->arg[0]) = reg(ic->arg[2]) & 0x7fffffffffffffffULL;
493 }
494 X(fneg)
495 {
496  reg(ic->arg[0]) = reg(ic->arg[2]) ^ 0x8000000000000000ULL;
497 }
498 
499 
500 /*
501  * addt, subt, mult, divt: Floating point arithmetic.
502  *
503  * arg[0] = pointer to rc (destination)
504  * arg[1] = pointer to ra (source)
505  * arg[2] = pointer to rb (source)
506  */
507 X(addt)
508 {
509  struct ieee_float_value fa, fb;
510  double res;
513  if (fa.nan | fb.nan)
514  res = 0.0;
515  else
516  res = fa.f + fb.f;
517  reg(ic->arg[0]) = ieee_store_float_value(res,
518  IEEE_FMT_D, fa.nan | fb.nan);
519 }
520 X(subt)
521 {
522  struct ieee_float_value fa, fb;
523  double res;
526  if (fa.nan | fb.nan)
527  res = 0.0;
528  else
529  res = fa.f - fb.f;
530  reg(ic->arg[0]) = ieee_store_float_value(res,
531  IEEE_FMT_D, fa.nan | fb.nan);
532 }
533 X(mult)
534 {
535  struct ieee_float_value fa, fb;
536  double res;
539  if (fa.nan | fb.nan)
540  res = 0.0;
541  else
542  res = fa.f * fb.f;
543  reg(ic->arg[0]) = ieee_store_float_value(res,
544  IEEE_FMT_D, fa.nan | fb.nan);
545 }
546 X(divt)
547 {
548  struct ieee_float_value fa, fb;
549  double res;
552  if (fa.nan | fb.nan || fb.f == 0)
553  res = 0.0;
554  else
555  res = fa.f / fb.f;
556  reg(ic->arg[0]) = ieee_store_float_value(res,
557  IEEE_FMT_D, fa.nan | fb.nan || fb.f == 0);
558 }
559 X(cmpteq)
560 {
561  struct ieee_float_value fa, fb;
562  int res = 0;
565  if (fa.nan | fb.nan)
566  res = 0;
567  else
568  res = fa.f == fb.f;
569  reg(ic->arg[0]) = res;
570 }
571 X(cmptlt)
572 {
573  struct ieee_float_value fa, fb;
574  int res = 0;
577  if (fa.nan | fb.nan)
578  res = 0;
579  else
580  res = fa.f < fb.f;
581  reg(ic->arg[0]) = res;
582 }
583 X(cmptle)
584 {
585  struct ieee_float_value fa, fb;
586  int res = 0;
589  if (fa.nan | fb.nan)
590  res = 0;
591  else
592  res = fa.f <= fb.f;
593  reg(ic->arg[0]) = res;
594 }
595 
596 
597 /*
598  * implver: Return CPU implver value.
599  *
600  * arg[0] = pointer to destination uint64_t
601  */
602 X(implver)
603 {
604  reg(ic->arg[0]) = cpu->cd.alpha.cpu_type.implver;
605 }
606 
607 
608 /*
609  * mull, mull_imm: Signed Multiply 32x32 => 32.
610  *
611  * arg[0] = pointer to destination uint64_t
612  * arg[1] = pointer to source uint64_t
613  * arg[2] = pointer to source uint64_t or immediate
614  */
615 X(mull)
616 {
617  int32_t a = reg(ic->arg[1]);
618  int32_t b = reg(ic->arg[2]);
619  reg(ic->arg[0]) = (int64_t)(int32_t)(a * b);
620 }
621 X(mull_imm)
622 {
623  int32_t a = reg(ic->arg[1]);
624  int32_t b = ic->arg[2];
625  reg(ic->arg[0]) = (int64_t)(int32_t)(a * b);
626 }
627 
628 
629 /*
630  * mulq, mulq_imm: Unsigned Multiply 64x64 => 64.
631  *
632  * arg[0] = pointer to destination uint64_t
633  * arg[1] = pointer to source uint64_t
634  * arg[2] = pointer to source uint64_t or immediate
635  */
636 X(mulq)
637 {
638  reg(ic->arg[0]) = reg(ic->arg[1]) * reg(ic->arg[2]);
639 }
640 X(mulq_imm)
641 {
642  reg(ic->arg[0]) = reg(ic->arg[1]) * ic->arg[2];
643 }
644 
645 
646 /*
647  * umulh: Unsigned Multiply 64x64 => 128. Store high part in dest reg.
648  *
649  * arg[0] = pointer to destination uint64_t
650  * arg[1] = pointer to source uint64_t
651  * arg[2] = pointer to source uint64_t
652  */
653 X(umulh)
654 {
655  uint64_t reshi = 0, reslo = 0;
656  uint64_t s1 = reg(ic->arg[1]), s2 = reg(ic->arg[2]);
657  int i, bit;
658 
659  for (i=0; i<64; i++) {
660  bit = (s1 & 0x8000000000000000ULL)? 1 : 0;
661  s1 <<= 1;
662 
663  /* If bit in s1 set, then add s2 to reshi/lo: */
664  if (bit) {
665  uint64_t old_reslo = reslo;
666  reslo += s2;
667  if (reslo < old_reslo)
668  reshi ++;
669  }
670 
671  if (i != 63) {
672  reshi <<= 1;
673  reshi += (reslo & 0x8000000000000000ULL? 1 : 0);
674  reslo <<= 1;
675  }
676  }
677 
678  reg(ic->arg[0]) = reshi;
679 }
680 
681 
682 /*
683  * lda: Load address.
684  *
685  * arg[0] = pointer to destination uint64_t
686  * arg[1] = pointer to source uint64_t
687  * arg[2] = offset (possibly as an int32_t)
688  */
689 X(lda)
690 {
691  reg(ic->arg[0]) = reg(ic->arg[1]) + (int64_t)(int32_t)ic->arg[2];
692 }
693 
694 
695 /*
696  * lda_0: Load address compared to the zero register.
697  *
698  * arg[0] = pointer to destination uint64_t
699  * arg[1] = ignored
700  * arg[2] = offset (possibly as an int32_t)
701  */
702 X(lda_0)
703 {
704  reg(ic->arg[0]) = (int64_t)(int32_t)ic->arg[2];
705 }
706 
707 
708 /*
709  * clear: Clear a 64-bit register.
710  *
711  * arg[0] = pointer to destination uint64_t
712  */
713 X(clear)
714 {
715  reg(ic->arg[0]) = 0;
716 }
717 
718 
719 /*
720  * rdcc: Read the Cycle Counter into a 64-bit register.
721  *
722  * arg[0] = pointer to destination uint64_t
723  */
724 X(rdcc)
725 {
726  reg(ic->arg[0]) = cpu->cd.alpha.pcc;
727 
728  /* TODO: actually keep the pcc updated! */
729  cpu->cd.alpha.pcc += 20;
730 }
731 
732 
733 #include "tmp_alpha_misc.cc"
734 
735 
736 /*****************************************************************************/
737 
738 
739 X(end_of_page)
740 {
741  /* Update the PC: (offset 0, but on the next page) */
746 
747  /* Find the new physical page and update the translation pointers: */
748  alpha_pc_to_pointers(cpu);
749 
750  /* end_of_page doesn't count as an executed instruction: */
752 }
753 
754 
755 /*****************************************************************************/
756 
757 
758 /*
759  * alpha_instr_to_be_translated():
760  *
761  * Translate an instruction word into an alpha_instr_call. ic is filled in with
762  * valid data for the translated instruction, or a "nothing" instruction if
763  * there was a translation failure. The newly translated instruction is then
764  * executed.
765  */
766 X(to_be_translated)
767 {
768  uint64_t addr, low_pc;
769  uint32_t iword;
770  unsigned char *page;
771  unsigned char ib[4];
772  void (*samepage_function)(struct cpu *, struct alpha_instr_call *);
773  int opcode, ra, rb, func, rc, imm, load, loadstore_type, fp, llsc;
774 
775  /* Figure out the (virtual) address of the instruction: */
776  low_pc = ((size_t)ic - (size_t)cpu->cd.alpha.cur_ic_page)
777  / sizeof(struct alpha_instr_call);
778  addr = cpu->pc & ~((ALPHA_IC_ENTRIES_PER_PAGE-1) <<
780  addr += (low_pc << ALPHA_INSTR_ALIGNMENT_SHIFT);
781  addr &= ~((1 << ALPHA_INSTR_ALIGNMENT_SHIFT) - 1);
782  cpu->pc = addr;
783 
784  /* Read the instruction word from memory: */
785  {
786  const uint32_t mask1 = (1 << DYNTRANS_L1N) - 1;
787  const uint32_t mask2 = (1 << DYNTRANS_L2N) - 1;
788  const uint32_t mask3 = (1 << DYNTRANS_L3N) - 1;
789  uint32_t x1 = (addr >> (64-DYNTRANS_L1N)) & mask1;
790  uint32_t x2 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2;
791  uint32_t x3 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N-
792  DYNTRANS_L3N)) & mask3;
793  struct DYNTRANS_L2_64_TABLE *l2 = cpu->cd.alpha.l1_64[x1];
794  struct DYNTRANS_L3_64_TABLE *l3 = l2->l3[x2];
795  page = l3->host_load[x3];
796  }
797 
798  if (page != NULL) {
799  /* fatal("TRANSLATION HIT!\n"); */
800  memcpy(ib, page + (addr & 8191), sizeof(ib));
801  } else {
802  /* fatal("TRANSLATION MISS!\n"); */
803  if (!cpu->memory_rw(cpu, cpu->mem, addr, &ib[0],
804  sizeof(ib), MEM_READ, CACHE_INSTRUCTION)) {
805  fatal("to_be_translated(): read failed: TODO\n");
806  goto bad;
807  }
808  }
809 
810  /* Alpha instruction words are always little-endian. Convert
811  to host order: */
812  {
813  uint32_t *p = (uint32_t *) ib;
814  iword = LE32_TO_HOST( *p );
815  }
816 
817 #define DYNTRANS_TO_BE_TRANSLATED_HEAD
818 #include "cpu_dyntrans.cc"
819 #undef DYNTRANS_TO_BE_TRANSLATED_HEAD
820 
821 
822  opcode = (iword >> 26) & 63;
823  ra = (iword >> 21) & 31;
824  rb = (iword >> 16) & 31;
825  func = (iword >> 5) & 0x7ff;
826  rc = iword & 31;
827  imm = iword & 0xffff;
828 
829  switch (opcode) {
830  case 0x00: /* CALL_PAL */
831  ic->f = instr(call_pal);
832  ic->arg[0] = (size_t) (iword & 0x3ffffff);
833  break;
834  case 0x08: /* LDA */
835  case 0x09: /* LDAH */
836  if (ra == ALPHA_ZERO) {
837  ic->f = instr(nop);
838  break;
839  }
840  /* TODO: A special case which is common is to add or subtract
841  a small offset from sp. */
842  ic->f = instr(lda);
843  ic->arg[0] = (size_t) &cpu->cd.alpha.r[ra];
844  ic->arg[1] = (size_t) &cpu->cd.alpha.r[rb];
845  if (rb == ALPHA_ZERO)
846  ic->f = instr(lda_0);
847  ic->arg[2] = (ssize_t)(int16_t)imm;
848  if (opcode == 0x09)
849  ic->arg[2] <<= 16;
850  break;
851  case 0x0b: /* LDQ_U */
852  case 0x0f: /* STQ_U */
853  if (ra == ALPHA_ZERO && opcode == 0x0b) {
854  ic->f = instr(nop);
855  break;
856  }
857  if (opcode == 0x0b)
858  ic->f = instr(ldq_u);
859  else
860  ic->f = instr(stq_u);
861  ic->arg[0] = (size_t) &cpu->cd.alpha.r[ra];
862  ic->arg[1] = (size_t) &cpu->cd.alpha.r[rb];
863  ic->arg[2] = (ssize_t)(int16_t)imm;
864  break;
865  case 0x0a:
866  case 0x0c:
867  case 0x0d:
868  case 0x0e:
869  case 0x22:
870  case 0x23:
871  case 0x26:
872  case 0x27:
873  case 0x28:
874  case 0x29:
875  case 0x2a:
876  case 0x2b:
877  case 0x2c:
878  case 0x2d:
879  case 0x2e:
880  case 0x2f:
881  loadstore_type = 0; fp = 0; load = 0; llsc = 0;
882  switch (opcode) {
883  case 0x0a: loadstore_type = 0; load = 1; break; /* ldbu */
884  case 0x0c: loadstore_type = 1; load = 1; break; /* ldwu */
885  case 0x0d: loadstore_type = 1; break; /* stw */
886  case 0x0e: loadstore_type = 0; break; /* stb */
887  case 0x22: loadstore_type = 2; load = 1; fp = 1; break; /*lds*/
888  case 0x23: loadstore_type = 3; load = 1; fp = 1; break; /*ldt*/
889  case 0x26: loadstore_type = 2; fp = 1; break; /* sts */
890  case 0x27: loadstore_type = 3; fp = 1; break; /* stt */
891  case 0x28: loadstore_type = 2; load = 1; break; /* ldl */
892  case 0x29: loadstore_type = 3; load = 1; break; /* ldq */
893  case 0x2a: loadstore_type = 2; load = llsc = 1; break;/* ldl_l*/
894  case 0x2b: loadstore_type = 3; load = llsc = 1; break;/* ldq_l*/
895  case 0x2c: loadstore_type = 2; break; /* stl */
896  case 0x2d: loadstore_type = 3; break; /* stq */
897  case 0x2e: loadstore_type = 2; llsc = 1; break; /* stl_c */
898  case 0x2f: loadstore_type = 3; llsc = 1; break; /* stq_c */
899  }
900  ic->f = alpha_loadstore[
901  loadstore_type + (imm==0? 4 : 0) + 8 * load
902  + 16 * llsc];
903  /* Load to the zero register is treated as a prefetch
904  hint. It is ignored here. */
905  if (load && ra == ALPHA_ZERO) {
906  ic->f = instr(nop);
907  break;
908  }
909  if (fp)
910  ic->arg[0] = (size_t) &cpu->cd.alpha.f[ra];
911  else
912  ic->arg[0] = (size_t) &cpu->cd.alpha.r[ra];
913  ic->arg[1] = (size_t) &cpu->cd.alpha.r[rb];
914  ic->arg[2] = (ssize_t)(int16_t)imm;
915  break;
916  case 0x10:
917  if (rc == ALPHA_ZERO) {
918  ic->f = instr(nop);
919  break;
920  }
921  ic->arg[0] = (size_t) &cpu->cd.alpha.r[rc];
922  ic->arg[1] = (size_t) &cpu->cd.alpha.r[ra];
923  if (func & 0x80)
924  ic->arg[2] = (size_t)((rb << 3) + (func >> 8));
925  else
926  ic->arg[2] = (size_t) &cpu->cd.alpha.r[rb];
927  switch (func & 0xff) {
928  case 0x00: ic->f = instr(addl); break;
929  case 0x02: ic->f = instr(s4addl); break;
930  case 0x09: ic->f = instr(subl); break;
931  case 0x0b: ic->f = instr(s4subl); break;
932  case 0x0f: ic->f = instr(cmpbge); break;
933  case 0x12: ic->f = instr(s8addl); break;
934  case 0x1b: ic->f = instr(s8subl); break;
935  case 0x1d: ic->f = instr(cmpult); break;
936  case 0x20: ic->f = instr(addq); break;
937  case 0x22: ic->f = instr(s4addq); break;
938  case 0x29: ic->f = instr(subq); break;
939  case 0x2b: ic->f = instr(s4subq); break;
940  case 0x2d: ic->f = instr(cmpeq); break;
941  case 0x32: ic->f = instr(s8addq); break;
942  case 0x3b: ic->f = instr(s8subq); break;
943  case 0x3d: ic->f = instr(cmpule); break;
944  case 0x4d: ic->f = instr(cmplt); break;
945  // case 0x69: ic->f = instr(subq_v); break;
946  case 0x6d: ic->f = instr(cmple); break;
947 
948  case 0x80: ic->f = instr(addl_imm); break;
949  case 0x82: ic->f = instr(s4addl_imm); break;
950  case 0x89: ic->f = instr(subl_imm); break;
951  case 0x8b: ic->f = instr(s4subl_imm); break;
952  case 0x8f: ic->f = instr(cmpbge_imm); break;
953  case 0x92: ic->f = instr(s8addl_imm); break;
954  case 0x9b: ic->f = instr(s8subl_imm); break;
955  case 0x9d: ic->f = instr(cmpult_imm); break;
956  case 0xa0: ic->f = instr(addq_imm); break;
957  case 0xa2: ic->f = instr(s4addq_imm); break;
958  case 0xa9: ic->f = instr(subq_imm); break;
959  case 0xab: ic->f = instr(s4subq_imm); break;
960  case 0xad: ic->f = instr(cmpeq_imm); break;
961  case 0xb2: ic->f = instr(s8addq_imm); break;
962  case 0xbb: ic->f = instr(s8subq_imm); break;
963  case 0xbd: ic->f = instr(cmpule_imm); break;
964  case 0xcd: ic->f = instr(cmplt_imm); break;
965  case 0xed: ic->f = instr(cmple_imm); break;
966 
967  default:if (!cpu->translation_readahead)
968  fatal("[ Alpha: unimplemented function 0x%03x "
969  "for opcode 0x%02x ]\n", func, opcode);
970  goto bad;
971  }
972  break;
973  case 0x11:
974  if (rc == ALPHA_ZERO) {
975  ic->f = instr(nop);
976  break;
977  }
978  ic->arg[0] = (size_t) &cpu->cd.alpha.r[rc];
979  ic->arg[1] = (size_t) &cpu->cd.alpha.r[ra];
980  if (func & 0x80)
981  ic->arg[2] = (size_t)((rb << 3) + (func >> 8));
982  else
983  ic->arg[2] = (size_t) &cpu->cd.alpha.r[rb];
984  switch (func & 0xff) {
985  case 0x00: ic->f = instr(and); break;
986  case 0x08: ic->f = instr(andnot); break;
987  case 0x14: ic->f = instr(cmovlbs); break;
988  case 0x16: ic->f = instr(cmovlbc); break;
989  case 0x20: ic->f = instr(or);
990  if (ra == ALPHA_ZERO || rb == ALPHA_ZERO) {
991  if (ra == ALPHA_ZERO)
992  ra = rb;
993  ic->f = alpha_mov_r_r[ra + rc*32];
994  }
995  break;
996  case 0x24: ic->f = instr(cmoveq); break;
997  case 0x26: ic->f = instr(cmovne); break;
998  case 0x28: ic->f = instr(ornot); break;
999  case 0x40: ic->f = instr(xor); break;
1000  case 0x44: ic->f = instr(cmovlt); break;
1001  case 0x46: ic->f = instr(cmovge); break;
1002  case 0x48: ic->f = instr(xornot); break;
1003  case 0x64: ic->f = instr(cmovle); break;
1004  case 0x66: ic->f = instr(cmovgt); break;
1005  case 0x80: ic->f = instr(and_imm); break;
1006  case 0x88: ic->f = instr(andnot_imm); break;
1007  case 0x94: ic->f = instr(cmovlbs_imm); break;
1008  case 0x96: ic->f = instr(cmovlbc_imm); break;
1009  case 0xa0: ic->f = instr(or_imm); break;
1010  case 0xa4: ic->f = instr(cmoveq_imm); break;
1011  case 0xa6: ic->f = instr(cmovne_imm); break;
1012  case 0xa8: ic->f = instr(ornot_imm); break;
1013  case 0xc0: ic->f = instr(xor_imm); break;
1014  case 0xc4: ic->f = instr(cmovlt_imm); break;
1015  case 0xc6: ic->f = instr(cmovge_imm); break;
1016  case 0xc8: ic->f = instr(xornot_imm); break;
1017  case 0xe4: ic->f = instr(cmovle_imm); break;
1018  case 0xe6: ic->f = instr(cmovgt_imm); break;
1019  case 0xec: ic->f = instr(implver); break;
1020  default:if (!cpu->translation_readahead)
1021  fatal("[ Alpha: unimplemented function 0x%03x "
1022  "for opcode 0x%02x ]\n", func, opcode);
1023  goto bad;
1024  }
1025  break;
1026  case 0x12:
1027  if (rc == ALPHA_ZERO) {
1028  ic->f = instr(nop);
1029  break;
1030  }
1031  ic->arg[0] = (size_t) &cpu->cd.alpha.r[rc];
1032  ic->arg[1] = (size_t) &cpu->cd.alpha.r[ra];
1033  if (func & 0x80)
1034  ic->arg[2] = (size_t)((rb << 3) + (func >> 8));
1035  else
1036  ic->arg[2] = (size_t) &cpu->cd.alpha.r[rb];
1037  switch (func & 0xff) {
1038  case 0x02: ic->f = instr(mskbl); break;
1039  case 0x06: ic->f = instr(extbl); break;
1040  case 0x0b: ic->f = instr(insbl); break;
1041  case 0x12: ic->f = instr(mskwl); break;
1042  case 0x16: ic->f = instr(extwl); break;
1043  case 0x1b: ic->f = instr(inswl); break;
1044  case 0x22: ic->f = instr(mskll); break;
1045  case 0x26: ic->f = instr(extll); break;
1046  case 0x2b: ic->f = instr(insll); break;
1047  case 0x30: ic->f = instr(zap); break;
1048  case 0x31: ic->f = instr(zapnot); break;
1049  case 0x32: ic->f = instr(mskql); break;
1050  case 0x34: ic->f = instr(srl); break;
1051  case 0x36: ic->f = instr(extql); break;
1052  case 0x39: ic->f = instr(sll); break;
1053  case 0x3b: ic->f = instr(insql); break;
1054  case 0x3c: ic->f = instr(sra); break;
1055  case 0x52: ic->f = instr(mskwh); break;
1056  case 0x57: ic->f = instr(inswh); break;
1057  case 0x5a: ic->f = instr(extwh); break;
1058  case 0x62: ic->f = instr(msklh); break;
1059  case 0x67: ic->f = instr(inslh); break;
1060  case 0x6a: ic->f = instr(extlh); break;
1061  case 0x72: ic->f = instr(mskqh); break;
1062  case 0x77: ic->f = instr(insqh); break;
1063  case 0x7a: ic->f = instr(extqh); break;
1064  case 0x82: ic->f = instr(mskbl_imm); break;
1065  case 0x86: ic->f = instr(extbl_imm); break;
1066  case 0x8b: ic->f = instr(insbl_imm); break;
1067  case 0x92: ic->f = instr(mskwl_imm); break;
1068  case 0x96: ic->f = instr(extwl_imm); break;
1069  case 0x9b: ic->f = instr(inswl_imm); break;
1070  case 0xa2: ic->f = instr(mskll_imm); break;
1071  case 0xa6: ic->f = instr(extll_imm); break;
1072  case 0xab: ic->f = instr(insll_imm); break;
1073  case 0xb0: ic->f = instr(zap_imm); break;
1074  case 0xb1: ic->f = instr(zapnot_imm); break;
1075  case 0xb2: ic->f = instr(mskql_imm); break;
1076  case 0xb4: ic->f = instr(srl_imm); break;
1077  case 0xb6: ic->f = instr(extql_imm); break;
1078  case 0xb9: ic->f = instr(sll_imm); break;
1079  case 0xbb: ic->f = instr(insql_imm); break;
1080  case 0xbc: ic->f = instr(sra_imm); break;
1081  case 0xd2: ic->f = instr(mskwh_imm); break;
1082  case 0xd7: ic->f = instr(inswh_imm); break;
1083  case 0xda: ic->f = instr(extwh_imm); break;
1084  case 0xe2: ic->f = instr(msklh_imm); break;
1085  case 0xe7: ic->f = instr(inslh_imm); break;
1086  case 0xea: ic->f = instr(extlh_imm); break;
1087  case 0xf2: ic->f = instr(mskqh_imm); break;
1088  case 0xf7: ic->f = instr(insqh_imm); break;
1089  case 0xfa: ic->f = instr(extqh_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 0x13:
1097  if (rc == ALPHA_ZERO) {
1098  ic->f = instr(nop);
1099  break;
1100  }
1101  ic->arg[0] = (size_t) &cpu->cd.alpha.r[rc];
1102  ic->arg[1] = (size_t) &cpu->cd.alpha.r[ra];
1103  if (func & 0x80)
1104  ic->arg[2] = (size_t)((rb << 3) + (func >> 8));
1105  else
1106  ic->arg[2] = (size_t) &cpu->cd.alpha.r[rb];
1107  // TODO: mulq/v etc? overflow detection
1108  // bit 0..6 are function, but 7 is "imm" bit.
1109  switch (func & 0xff) {
1110  case 0x00: ic->f = instr(mull); break;
1111  case 0x20: ic->f = instr(mulq); break;
1112  case 0x30: ic->f = instr(umulh); break;
1113  case 0x80: ic->f = instr(mull_imm); break;
1114  case 0xa0: ic->f = instr(mulq_imm); break;
1115  default:if (!cpu->translation_readahead)
1116  fatal("[ Alpha: unimplemented function 0x%03x "
1117  "for opcode 0x%02x ]\n", func, opcode);
1118  goto bad;
1119  }
1120  break;
1121  case 0x16:
1122  if (rc == ALPHA_ZERO) {
1123  ic->f = instr(nop);
1124  break;
1125  }
1126  ic->arg[0] = (size_t) &cpu->cd.alpha.f[rc];
1127  ic->arg[1] = (size_t) &cpu->cd.alpha.f[ra];
1128  ic->arg[2] = (size_t) &cpu->cd.alpha.f[rb];
1129  switch (func & 0x7ff) {
1130  case 0x02f: ic->f = instr(cvttq_c); break;
1131  case 0x0a0: ic->f = instr(addt); break;
1132  case 0x0a1: ic->f = instr(subt); break;
1133  case 0x0a2: ic->f = instr(mult); break;
1134  case 0x0a3: ic->f = instr(divt); break;
1135  case 0x0a5: ic->f = instr(cmpteq); break;
1136  case 0x0a6: ic->f = instr(cmptlt); break;
1137  case 0x0a7: ic->f = instr(cmptle); break;
1138  case 0x0be: ic->f = instr(cvtqt); 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 0x17:
1146  if (rc == ALPHA_ZERO) {
1147  ic->f = instr(nop);
1148  break;
1149  }
1150  ic->arg[0] = (size_t) &cpu->cd.alpha.f[rc];
1151  ic->arg[1] = (size_t) &cpu->cd.alpha.f[ra];
1152  ic->arg[2] = (size_t) &cpu->cd.alpha.f[rb];
1153  switch (func & 0x7ff) {
1154  case 0x020:
1155  /* fabs (or fclr): */
1156  if (ra == 31 && rb == 31)
1157  ic->f = instr(clear);
1158  else
1159  ic->f = instr(fabs);
1160  break;
1161  case 0x021:
1162  ic->f = instr(fneg);
1163  break;
1164  default:if (!cpu->translation_readahead)
1165  fatal("[ Alpha: unimplemented function 0x%03x "
1166  "for opcode 0x%02x ]\n", func, opcode);
1167  goto bad;
1168  }
1169  break;
1170  case 0x18:
1171  switch (iword & 0xffff) {
1172  case 0x4000: /* mb */
1173  case 0x4400: /* wmb */
1174  ic->f = instr(nop);
1175  break;
1176  case 0xc000: /* rdcc ra */
1177  if (ra == ALPHA_ZERO) {
1178  ic->f = instr(nop);
1179  break;
1180  }
1181  ic->arg[0] = (size_t) &cpu->cd.alpha.r[ra];
1182  ic->f = instr(rdcc);
1183  break;
1184  default:if (!cpu->translation_readahead)
1185  fatal("[ Alpha: unimplemented function 0x%03x "
1186  "for opcode 0x%02x ]\n", func, opcode);
1187  goto bad;
1188  }
1189  break;
1190  case 0x1a:
1191  switch ((iword >> 14) & 3) {
1192  case 0: /* JMP */
1193  case 1: /* JSR */
1194  case 2: /* RET */
1195  ic->arg[0] = (size_t) &cpu->cd.alpha.r[ra];
1196  ic->arg[1] = (size_t) &cpu->cd.alpha.r[rb];
1197  if (ra == ALPHA_ZERO) {
1198  if (cpu->machine->show_trace_tree &&
1199  rb == ALPHA_RA)
1200  ic->f = instr(jsr_0_trace);
1201  else
1202  ic->f = instr(jsr_0);
1203  } else {
1204  if (cpu->machine->show_trace_tree)
1205  ic->f = instr(jsr_trace);
1206  else
1207  ic->f = instr(jsr);
1208  }
1209  break;
1210  default:if (!cpu->translation_readahead)
1211  fatal("[ Alpha: unimpl JSR type %i, ra=%i "
1212  "rb=%i ]\n", ((iword >> 14) & 3), ra, rb);
1213  goto bad;
1214  }
1215  break;
1216  case 0x30: /* BR */
1217  case 0x31: /* FBEQ */
1218  case 0x34: /* BSR */
1219  case 0x35: /* FBNE */
1220  case 0x38: /* BLBC */
1221  case 0x39: /* BEQ */
1222  case 0x3a: /* BLT */
1223  case 0x3b: /* BLE */
1224  case 0x3c: /* BLBS */
1225  case 0x3d: /* BNE */
1226  case 0x3e: /* BGE */
1227  case 0x3f: /* BGT */
1228  /* To avoid a GCC warning: */
1229  samepage_function = instr(nop);
1230  fp = 0;
1231  switch (opcode) {
1232  case 0x30:
1233  case 0x34:
1234  ic->f = instr(br);
1235  samepage_function = instr(br_samepage);
1236  if (ra != ALPHA_ZERO) {
1237  ic->f = instr(br_return);
1238  samepage_function = instr(br_return_samepage);
1239  }
1240  break;
1241  case 0x38:
1242  ic->f = instr(blbc);
1243  samepage_function = instr(blbc_samepage);
1244  break;
1245  case 0x31:
1246  fp = 1;
1247  case 0x39:
1248  ic->f = instr(beq);
1249  samepage_function = instr(beq_samepage);
1250  break;
1251  case 0x3a:
1252  ic->f = instr(blt);
1253  samepage_function = instr(blt_samepage);
1254  break;
1255  case 0x3b:
1256  ic->f = instr(ble);
1257  samepage_function = instr(ble_samepage);
1258  break;
1259  case 0x3c:
1260  ic->f = instr(blbs);
1261  samepage_function = instr(blbs_samepage);
1262  break;
1263  case 0x35:
1264  fp = 1;
1265  case 0x3d:
1266  ic->f = instr(bne);
1267  samepage_function = instr(bne_samepage);
1268  break;
1269  case 0x3e:
1270  ic->f = instr(bge);
1271  samepage_function = instr(bge_samepage);
1272  break;
1273  case 0x3f:
1274  ic->f = instr(bgt);
1275  samepage_function = instr(bgt_samepage);
1276  break;
1277  }
1278  if (fp)
1279  ic->arg[1] = (size_t) &cpu->cd.alpha.f[ra];
1280  else
1281  ic->arg[1] = (size_t) &cpu->cd.alpha.r[ra];
1282  ic->arg[0] = (iword & 0x001fffff) << 2;
1283  /* Sign-extend: */
1284  if (ic->arg[0] & 0x00400000)
1285  ic->arg[0] |= 0xffffffffff800000ULL;
1286  /* Branches are calculated as PC + 4 + offset. */
1287  ic->arg[0] = (size_t)(ic->arg[0] + 4);
1288  /* Special case: branch within the same page: */
1289  {
1290  uint64_t mask_within_page =
1291  ((ALPHA_IC_ENTRIES_PER_PAGE-1) << 2) | 3;
1292  uint64_t old_pc = addr;
1293  uint64_t new_pc = old_pc + (int32_t)ic->arg[0];
1294  if ((old_pc & ~mask_within_page) ==
1295  (new_pc & ~mask_within_page)) {
1296  ic->f = samepage_function;
1297  ic->arg[0] = (size_t) (
1298  cpu->cd.alpha.cur_ic_page +
1299  ((new_pc & mask_within_page) >> 2));
1300  }
1301  }
1302  break;
1303  default:if (!cpu->translation_readahead)
1304  fatal("[ UNIMPLEMENTED Alpha opcode 0x%x ]\n", opcode);
1305  goto bad;
1306  }
1307 
1308 
1309 #define DYNTRANS_TO_BE_TRANSLATED_TAIL
1310 #include "cpu_dyntrans.cc"
1311 #undef DYNTRANS_TO_BE_TRANSLATED_TAIL
1312 }
1313 
void fatal(const char *fmt,...)
Definition: main.cc:152
page
void COMBINE() nop(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
struct arm_instr_call * ic
union cpu::@1 cd
struct memory * mem
Definition: cpu.h:362
#define ALPHA_RA
Definition: cpu_alpha.h:104
uint64_t pcc
Definition: cpu_alpha.h:157
struct machine * machine
Definition: cpu.h:328
#define MEM_READ
Definition: memory.h:116
void COMBINE() sll(struct cpu *cpu, struct mips_instr_call *ic, int low_addr)
#define instr(n)
#define DYNTRANS_L2_64_TABLE
void ieee_interpret_float_value(uint64_t x, struct ieee_float_value *fvp, int fmt)
Definition: float_emul.cc:49
#define ALPHA_INSTR_ALIGNMENT_SHIFT
Definition: cpu_alpha.h:123
#define reg(x)
void alpha_palcode(struct cpu *cpu, uint32_t palcode)
void(* alpha_mov_r_r[32 *31])(struct cpu *, struct alpha_instr_call *)
int translation_readahead
Definition: cpu.h:424
uint64_t pc
Definition: cpu.h:383
#define ALPHA_IC_ENTRIES_PER_PAGE
Definition: cpu_alpha.h:125
#define LE32_TO_HOST(x)
Definition: misc.h:180
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:365
#define DYNTRANS_L2N
uint8_t running
Definition: cpu.h:353
#define ALPHA_ZERO
Definition: cpu_alpha.h:109
void(* alpha_loadstore[32])(struct cpu *, struct alpha_instr_call *)
void cpu_functioncall_trace(struct cpu *cpu, uint64_t f)
Definition: cpu.cc:219
struct alpha_cpu_type_def cpu_type
Definition: cpu_alpha.h:144
uint32_t addr
void cpu_functioncall_trace_return(struct cpu *cpu)
Definition: cpu.cc:275
uint64_t r[N_ALPHA_REGS]
Definition: cpu_alpha.h:151
Definition: cpu.h:326
#define DYNTRANS_L1N
Definition: cpu.h:222
int n_translated_instrs
Definition: cpu.h:427
#define CACHE_INSTRUCTION
Definition: memory.h:122
void load(FILE *fh, unsigned char *ptr, unsigned long sz)
uint64_t ieee_store_float_value(double nf, int fmt, int nan)
Definition: float_emul.cc:185
#define DYNTRANS_L3N
struct alpha_cpu alpha
Definition: cpu.h:440
X(nop)
addr & if(addr >=0x24 &&page !=NULL)
#define IEEE_FMT_D
Definition: float_emul.h:44
#define DYNTRANS_L3_64_TABLE
int show_trace_tree
Definition: machine.h:164
uint64_t f[N_ALPHA_REGS]
Definition: cpu_alpha.h:152

Generated on Sun Sep 30 2018 16:05:18 for GXemul by doxygen 1.8.13