25 |
* SUCH DAMAGE. |
* SUCH DAMAGE. |
26 |
* |
* |
27 |
* |
* |
28 |
* $Id: cpu_alpha_instr.c,v 1.7 2006/02/09 22:40:27 debug Exp $ |
* $Id: cpu_alpha_instr.c,v 1.12 2006/06/30 20:22:53 debug Exp $ |
29 |
* |
* |
30 |
* Alpha instructions. |
* Alpha instructions. |
31 |
* |
* |
749 |
{ |
{ |
750 |
uint64_t addr, low_pc; |
uint64_t addr, low_pc; |
751 |
uint32_t iword; |
uint32_t iword; |
|
struct alpha_vph_page *vph_p; |
|
752 |
unsigned char *page; |
unsigned char *page; |
753 |
unsigned char ib[4]; |
unsigned char ib[4]; |
754 |
void (*samepage_function)(struct cpu *, struct alpha_instr_call *); |
void (*samepage_function)(struct cpu *, struct alpha_instr_call *); |
755 |
int opcode, ra, rb, func, rc, imm, load, loadstore_type, fp, llsc; |
int opcode, ra, rb, func, rc, imm, load, loadstore_type, fp, llsc; |
|
#ifdef DYNTRANS_BACKEND |
|
|
int simple = 0; |
|
|
#endif |
|
756 |
|
|
757 |
/* Figure out the (virtual) address of the instruction: */ |
/* Figure out the (virtual) address of the instruction: */ |
758 |
low_pc = ((size_t)ic - (size_t)cpu->cd.alpha.cur_ic_page) |
low_pc = ((size_t)ic - (size_t)cpu->cd.alpha.cur_ic_page) |
764 |
cpu->pc = addr; |
cpu->pc = addr; |
765 |
|
|
766 |
/* Read the instruction word from memory: */ |
/* Read the instruction word from memory: */ |
767 |
if ((addr >> ALPHA_TOPSHIFT) == 0) { |
{ |
768 |
vph_p = cpu->cd.alpha.vph_table0[(addr >> |
const uint32_t mask1 = (1 << DYNTRANS_L1N) - 1; |
769 |
ALPHA_LEVEL0_SHIFT) & 8191]; |
const uint32_t mask2 = (1 << DYNTRANS_L2N) - 1; |
770 |
page = vph_p->host_load[(addr >> ALPHA_LEVEL1_SHIFT) & 8191]; |
const uint32_t mask3 = (1 << DYNTRANS_L3N) - 1; |
771 |
} else if ((addr >> ALPHA_TOPSHIFT) == ALPHA_TOP_KERNEL) { |
uint32_t x1 = (addr >> (64-DYNTRANS_L1N)) & mask1; |
772 |
vph_p = cpu->cd.alpha.vph_table0_kernel[(addr >> |
uint32_t x2 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N)) & mask2; |
773 |
ALPHA_LEVEL0_SHIFT) & 8191]; |
uint32_t x3 = (addr >> (64-DYNTRANS_L1N-DYNTRANS_L2N- |
774 |
page = vph_p->host_load[(addr >> ALPHA_LEVEL1_SHIFT) & 8191]; |
DYNTRANS_L3N)) & mask3; |
775 |
} else |
struct DYNTRANS_L2_64_TABLE *l2 = cpu->cd.alpha.l1_64[x1]; |
776 |
page = NULL; |
struct DYNTRANS_L3_64_TABLE *l3 = l2->l3[x2]; |
777 |
|
page = l3->host_load[x3]; |
778 |
|
} |
779 |
|
|
780 |
if (page != NULL) { |
if (page != NULL) { |
781 |
/* fatal("TRANSLATION HIT!\n"); */ |
/* fatal("TRANSLATION HIT!\n"); */ |
789 |
} |
} |
790 |
} |
} |
791 |
|
|
792 |
#ifdef HOST_LITTLE_ENDIAN |
/* Alpha instruction words are always little-endian. Convert |
793 |
iword = *((uint32_t *)&ib[0]); |
to host order: */ |
794 |
#else |
iword = LE32_TO_HOST( *((uint32_t *)&ib[0]) ); |
|
iword = ib[0] + (ib[1]<<8) + (ib[2]<<16) + (ib[3]<<24); |
|
|
#endif |
|
|
|
|
|
/* fatal("{ Alpha: translating pc=0x%016llx iword=0x%08x }\n", |
|
|
(long long)addr, (int)iword); */ |
|
795 |
|
|
796 |
|
|
797 |
#define DYNTRANS_TO_BE_TRANSLATED_HEAD |
#define DYNTRANS_TO_BE_TRANSLATED_HEAD |
879 |
} |
} |
880 |
ic->f = alpha_loadstore[ |
ic->f = alpha_loadstore[ |
881 |
loadstore_type + (imm==0? 4 : 0) + 8 * load |
loadstore_type + (imm==0? 4 : 0) + 8 * load |
882 |
+ (cpu->machine->dyntrans_alignment_check? 16:0) |
+ 16 * llsc]; |
|
+ 32 * llsc]; |
|
883 |
/* Load to the zero register is treated as a prefetch |
/* Load to the zero register is treated as a prefetch |
884 |
hint. It is ignored here. */ |
hint. It is ignored here. */ |
885 |
if (load && ra == ALPHA_ZERO) { |
if (load && ra == ALPHA_ZERO) { |
909 |
case 0x02: ic->f = instr(s4addl); break; |
case 0x02: ic->f = instr(s4addl); break; |
910 |
case 0x09: ic->f = instr(subl); break; |
case 0x09: ic->f = instr(subl); break; |
911 |
case 0x0b: ic->f = instr(s4subl); break; |
case 0x0b: ic->f = instr(s4subl); break; |
912 |
|
case 0x0f: ic->f = instr(cmpbge); break; |
913 |
case 0x12: ic->f = instr(s8addl); break; |
case 0x12: ic->f = instr(s8addl); break; |
914 |
case 0x1b: ic->f = instr(s8subl); break; |
case 0x1b: ic->f = instr(s8subl); break; |
915 |
case 0x1d: ic->f = instr(cmpult); break; |
case 0x1d: ic->f = instr(cmpult); break; |
928 |
case 0x82: ic->f = instr(s4addl_imm); break; |
case 0x82: ic->f = instr(s4addl_imm); break; |
929 |
case 0x89: ic->f = instr(subl_imm); break; |
case 0x89: ic->f = instr(subl_imm); break; |
930 |
case 0x8b: ic->f = instr(s4subl_imm); break; |
case 0x8b: ic->f = instr(s4subl_imm); break; |
931 |
|
case 0x8f: ic->f = instr(cmpbge_imm); break; |
932 |
case 0x92: ic->f = instr(s8addl_imm); break; |
case 0x92: ic->f = instr(s8addl_imm); break; |
933 |
case 0x9b: ic->f = instr(s8subl_imm); break; |
case 0x9b: ic->f = instr(s8subl_imm); break; |
934 |
case 0x9d: ic->f = instr(cmpult_imm); break; |
case 0x9d: ic->f = instr(cmpult_imm); break; |