MIPS: Get rid of #if style config checks in the ISA description.
This commit is contained in:
@@ -163,12 +163,11 @@ decode OPCODE_HI default Unknown::unknown() {
|
||||
format BasicOp {
|
||||
0x2: movz({{ Rd = (Rt == 0) ? Rs : Rd; }});
|
||||
0x3: movn({{ Rd = (Rt != 0) ? Rs : Rd; }});
|
||||
#if FULL_SYSTEM
|
||||
0x4: syscall({{ fault = new SystemCallFault(); }});
|
||||
#else
|
||||
0x4: syscall({{ xc->syscall(R2); }},
|
||||
IsSerializeAfter, IsNonSpeculative);
|
||||
#endif
|
||||
0x4: decode FULL_SYSTEM {
|
||||
0: syscall_se({{ xc->syscall(R2); }},
|
||||
IsSerializeAfter, IsNonSpeculative);
|
||||
default: syscall({{ fault = new SystemCallFault(); }});
|
||||
}
|
||||
0x7: sync({{ ; }}, IsMemBarrier);
|
||||
0x5: break({{fault = new BreakpointFault();}});
|
||||
}
|
||||
@@ -211,44 +210,21 @@ decode OPCODE_HI default Unknown::unknown() {
|
||||
0x0: decode FUNCTION_LO {
|
||||
format IntOp {
|
||||
0x0: add({{
|
||||
/* More complicated since an ADD can cause
|
||||
an arithmetic overflow exception */
|
||||
int64_t Src1 = Rs.sw;
|
||||
int64_t Src2 = Rt.sw;
|
||||
int64_t temp_result;
|
||||
#if FULL_SYSTEM
|
||||
if (((Src1 >> 31) & 1) == 1)
|
||||
Src1 |= 0x100000000LL;
|
||||
#endif
|
||||
temp_result = Src1 + Src2;
|
||||
#if FULL_SYSTEM
|
||||
if (bits(temp_result, 31) ==
|
||||
bits(temp_result, 32)) {
|
||||
#endif
|
||||
Rd.sw = temp_result;
|
||||
#if FULL_SYSTEM
|
||||
} else {
|
||||
IntReg result;
|
||||
Rd = result = Rs + Rt;
|
||||
if (FULL_SYSTEM &&
|
||||
findOverflow(32, result, Rs, Rt)) {
|
||||
fault = new ArithmeticFault();
|
||||
}
|
||||
#endif
|
||||
}});
|
||||
0x1: addu({{ Rd.sw = Rs.sw + Rt.sw;}});
|
||||
0x2: sub({{
|
||||
/* More complicated since an SUB can cause
|
||||
an arithmetic overflow exception */
|
||||
int64_t Src1 = Rs.sw;
|
||||
int64_t Src2 = Rt.sw;
|
||||
int64_t temp_result = Src1 - Src2;
|
||||
#if FULL_SYSTEM
|
||||
if (bits(temp_result, 31) ==
|
||||
bits(temp_result, 32)) {
|
||||
#endif
|
||||
Rd.sw = temp_result;
|
||||
#if FULL_SYSTEM
|
||||
} else {
|
||||
IntReg result;
|
||||
Rd = result = Rs - Rt;
|
||||
if (FULL_SYSTEM &&
|
||||
findOverflow(32, result, Rs, ~Rt)) {
|
||||
fault = new ArithmeticFault();
|
||||
}
|
||||
#endif
|
||||
}});
|
||||
0x3: subu({{ Rd.sw = Rs.sw - Rt.sw; }});
|
||||
0x4: and({{ Rd = Rs & Rt; }});
|
||||
@@ -347,23 +323,12 @@ decode OPCODE_HI default Unknown::unknown() {
|
||||
0x1: decode OPCODE_LO {
|
||||
format IntImmOp {
|
||||
0x0: addi({{
|
||||
int64_t Src1 = Rs.sw;
|
||||
int64_t Src2 = imm;
|
||||
int64_t temp_result;
|
||||
#if FULL_SYSTEM
|
||||
if (((Src1 >> 31) & 1) == 1)
|
||||
Src1 |= 0x100000000LL;
|
||||
#endif
|
||||
temp_result = Src1 + Src2;
|
||||
#if FULL_SYSTEM
|
||||
if (bits(temp_result, 31) == bits(temp_result, 32)) {
|
||||
#endif
|
||||
Rt.sw = temp_result;
|
||||
#if FULL_SYSTEM
|
||||
} else {
|
||||
IntReg result;
|
||||
Rt = result = Rs + imm;
|
||||
if (FULL_SYSTEM &&
|
||||
findOverflow(32, result, Rs, imm)) {
|
||||
fault = new ArithmeticFault();
|
||||
}
|
||||
#endif
|
||||
}});
|
||||
0x1: addiu({{ Rt.sw = Rs.sw + imm; }});
|
||||
0x2: slti({{ Rt.sw = (Rs.sw < imm) ? 1 : 0 }});
|
||||
@@ -1516,11 +1481,10 @@ decode OPCODE_HI default Unknown::unknown() {
|
||||
if (Rs<2:0> == 0) {
|
||||
Fd.ud = Fs.ud;
|
||||
} else if (Rs<2:0> == 4) {
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
Fd.ud = Fs.ud<31:0> << 32 | Ft.ud<63:32>;
|
||||
#elif BYTE_ORDER == LITTLE_ENDIAN
|
||||
Fd.ud = Ft.ud<31:0> << 32 | Fs.ud<63:32>;
|
||||
#endif
|
||||
if (GuestByteOrder == BigEndianByteOrder)
|
||||
Fd.ud = Fs.ud<31:0> << 32 | Ft.ud<63:32>;
|
||||
else
|
||||
Fd.ud = Ft.ud<31:0> << 32 | Fs.ud<63:32>;
|
||||
} else {
|
||||
Fd.ud = Fd.ud;
|
||||
}
|
||||
@@ -2468,14 +2432,12 @@ decode OPCODE_HI default Unknown::unknown() {
|
||||
}
|
||||
}
|
||||
}
|
||||
0x3: decode OP {
|
||||
#if FULL_SYSTEM
|
||||
0x0: FailUnimpl::rdhwr();
|
||||
#else
|
||||
0x0: decode RD {
|
||||
29: BasicOp::rdhwr({{ Rt = TpValue; }});
|
||||
0x3: decode OP default FailUnimpl::rdhwr() {
|
||||
0x0: decode FULL_SYSTEM {
|
||||
0: decode RD {
|
||||
29: BasicOp::rdhwr_se({{ Rt = TpValue; }});
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -124,30 +124,28 @@ def template CP1Execute {{
|
||||
def template ControlTLBExecute {{
|
||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc, Trace::InstRecord *traceData) const
|
||||
{
|
||||
Fault fault = NoFault;
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
Fault fault = NoFault;
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
|
||||
#if FULL_SYSTEM
|
||||
if (FULL_SYSTEM) {
|
||||
if (isCoprocessor0Enabled(xc)) {
|
||||
if(isMMUTLB(xc)){
|
||||
%(code)s;
|
||||
} else {
|
||||
fault = new ReservedInstructionFault();
|
||||
}
|
||||
if(isMMUTLB(xc)){
|
||||
%(code)s;
|
||||
} else {
|
||||
fault = new ReservedInstructionFault();
|
||||
}
|
||||
} else {
|
||||
fault = new CoprocessorUnusableFault(0);
|
||||
fault = new CoprocessorUnusableFault(0);
|
||||
}
|
||||
#else // Syscall Emulation Mode - No TLB Instructions
|
||||
} else { // Syscall Emulation Mode - No TLB Instructions
|
||||
fault = new ReservedInstructionFault();
|
||||
#endif
|
||||
|
||||
if(fault == NoFault)
|
||||
{
|
||||
%(op_wb)s;
|
||||
}
|
||||
return fault;
|
||||
}
|
||||
|
||||
if (fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
return fault;
|
||||
}
|
||||
}};
|
||||
|
||||
@@ -175,67 +173,49 @@ output decoder {{
|
||||
}};
|
||||
|
||||
output exec {{
|
||||
bool isCoprocessorEnabled(%(CPU_exec_context)s *xc, unsigned cop_num)
|
||||
bool
|
||||
isCoprocessorEnabled(%(CPU_exec_context)s *xc, unsigned cop_num)
|
||||
{
|
||||
#if !FULL_SYSTEM
|
||||
return true;
|
||||
#else
|
||||
MiscReg Stat = xc->readMiscReg(MISCREG_STATUS);
|
||||
switch(cop_num)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
MiscReg Dbg = xc->readMiscReg(MISCREG_DEBUG);
|
||||
if((Stat & 0x10000006) == 0 // EXL, ERL or CU0 set, CP0 accessible
|
||||
&& (Dbg & 0x40000000) == 0 // DM bit set, CP0 accessible
|
||||
&& (Stat & 0x00000018) != 0) { // KSU = 0, kernel mode is base mode
|
||||
// Unable to use Status_CU0, etc directly, using bitfields & masks
|
||||
return false;
|
||||
}
|
||||
if (!FULL_SYSTEM)
|
||||
return true;
|
||||
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if((Stat & 0x20000000) == 0) // CU1 is reset
|
||||
return false;
|
||||
break;
|
||||
case 2:
|
||||
if((Stat & 0x40000000) == 0) // CU2 is reset
|
||||
return false;
|
||||
break;
|
||||
case 3:
|
||||
if((Stat & 0x80000000) == 0) // CU3 is reset
|
||||
return false;
|
||||
break;
|
||||
default: panic("Invalid Coprocessor Number Specified");
|
||||
break;
|
||||
MiscReg Stat = xc->readMiscReg(MISCREG_STATUS);
|
||||
if (cop_num == 0) {
|
||||
MiscReg Dbg = xc->readMiscReg(MISCREG_DEBUG);
|
||||
// In Stat, EXL, ERL or CU0 set, CP0 accessible
|
||||
// In Dbg, DM bit set, CP0 accessible
|
||||
// In Stat, KSU = 0, kernel mode is base mode
|
||||
return (Stat & 0x10000006) ||
|
||||
(Dbg & 0x40000000) ||
|
||||
!(Stat & 0x00000018);
|
||||
} else if (cop_num < 4) {
|
||||
return Stat & (0x10000000 << cop_num); // CU is reset
|
||||
} else {
|
||||
panic("Invalid Coprocessor Number Specified");
|
||||
}
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
bool inline isCoprocessor0Enabled(%(CPU_exec_context)s *xc)
|
||||
|
||||
bool inline
|
||||
isCoprocessor0Enabled(%(CPU_exec_context)s *xc)
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
MiscReg Stat = xc->readMiscRegNoEffect(MISCREG_STATUS);
|
||||
MiscReg Dbg = xc->readMiscRegNoEffect(MISCREG_DEBUG);
|
||||
if((Stat & 0x10000006) == 0 // EXL, ERL or CU0 set, CP0 accessible
|
||||
&& (Dbg & 0x40000000) == 0 // DM bit set, CP0 accessible
|
||||
&& (Stat & 0x00000018) != 0) { // KSU = 0, kernel mode is base mode
|
||||
// Unable to use Status_CU0, etc directly, using bitfields & masks
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
//printf("Syscall Emulation Mode: CP0 Enable Check defaults to TRUE\n");
|
||||
#endif
|
||||
return true;
|
||||
if (FULL_SYSTEM) {
|
||||
MiscReg Stat = xc->readMiscReg(MISCREG_STATUS);
|
||||
MiscReg Dbg = xc->readMiscReg(MISCREG_DEBUG);
|
||||
// In Stat, EXL, ERL or CU0 set, CP0 accessible
|
||||
// In Dbg, DM bit set, CP0 accessible
|
||||
// In Stat KSU = 0, kernel mode is base mode
|
||||
return (Stat & 0x10000006) || (Dbg & 0x40000000) ||
|
||||
!(Stat & 0x00000018);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
bool isMMUTLB(%(CPU_exec_context)s *xc)
|
||||
|
||||
bool
|
||||
isMMUTLB(%(CPU_exec_context)s *xc)
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
if((xc->readMiscRegNoEffect(MISCREG_CONFIG) & 0x00000380)==0x80)
|
||||
return true;
|
||||
#endif
|
||||
return false;
|
||||
MiscReg Config = xc->readMiscReg(MISCREG_CONFIG);
|
||||
return FULL_SYSTEM && (Config & 0x380) == 0x80;
|
||||
}
|
||||
}};
|
||||
|
||||
|
||||
@@ -140,28 +140,18 @@ output decoder {{
|
||||
}};
|
||||
|
||||
output exec {{
|
||||
bool isDspEnabled(%(CPU_exec_context)s *xc)
|
||||
bool
|
||||
isDspEnabled(%(CPU_exec_context)s *xc)
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
if( bits( xc->readMiscReg(MISCREG_STATUS), 24, 24 ) == 0 )
|
||||
return false;
|
||||
#else
|
||||
//printf("Syscall Emulation Mode: isDspEnabled() check defaults to TRUE\n");
|
||||
#endif
|
||||
return true;
|
||||
return !FULL_SYSTEM || bits(xc->readMiscReg(MISCREG_STATUS), 24);
|
||||
}
|
||||
}};
|
||||
|
||||
output exec {{
|
||||
bool isDspPresent(%(CPU_exec_context)s *xc)
|
||||
bool
|
||||
isDspPresent(%(CPU_exec_context)s *xc)
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
if( bits( xc->readMiscReg(MISCREG_CONFIG3), 10, 10 ) == 0 )
|
||||
return false;
|
||||
#else
|
||||
//printf("Syscall Emulation Mode: isDspPresent() check defaults to TRUE\n");
|
||||
#endif
|
||||
return true;
|
||||
return !FULL_SYSTEM || bits(xc->readMiscReg(MISCREG_CONFIG3), 10);
|
||||
}
|
||||
}};
|
||||
|
||||
|
||||
@@ -174,9 +174,8 @@ def template FloatingPointExecute {{
|
||||
|
||||
//When is the right time to reset cause bits?
|
||||
//start of every instruction or every cycle?
|
||||
#if FULL_SYSTEM
|
||||
fpResetCauseBits(xc);
|
||||
#endif
|
||||
if (FULL_SYSTEM)
|
||||
fpResetCauseBits(xc);
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
|
||||
@@ -191,12 +190,12 @@ def template FloatingPointExecute {{
|
||||
//----
|
||||
//Check for IEEE 754 FP Exceptions
|
||||
//fault = fpNanOperands((FPOp*)this, xc, Fd, traceData);
|
||||
if (
|
||||
#if FULL_SYSTEM
|
||||
!fpInvalidOp((FPOp*)this, xc, Fd, traceData) &&
|
||||
#endif
|
||||
fault == NoFault)
|
||||
{
|
||||
bool invalid_op = false;
|
||||
if (FULL_SYSTEM) {
|
||||
invalid_op =
|
||||
fpInvalidOp((FPOp*)this, xc, Fd, traceData);
|
||||
}
|
||||
if (!invalid_op && fault == NoFault) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -542,12 +542,13 @@ def format StoreFPIndexedMemory(memacc_code, ea_code = {{ EA = Rs + Rt; }},
|
||||
|
||||
def format LoadUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3; }},
|
||||
mem_flags = [], inst_flags = []) {{
|
||||
decl_code = 'uint32_t mem_word = Mem.uw;\n'
|
||||
decl_code += 'uint32_t unalign_addr = Rs + disp;\n'
|
||||
decl_code += 'uint32_t byte_offset = unalign_addr & 3;\n'
|
||||
decl_code += '#if BYTE_ORDER == BIG_ENDIAN\n'
|
||||
decl_code += '\tbyte_offset ^= 3;\n'
|
||||
decl_code += '#endif\n'
|
||||
decl_code = '''
|
||||
uint32_t mem_word = Mem.uw;
|
||||
uint32_t unalign_addr = Rs + disp;
|
||||
uint32_t byte_offset = unalign_addr & 3;
|
||||
if (GuestByteOrder == BigEndianByteOrder)
|
||||
byte_offset ^= 3;
|
||||
'''
|
||||
|
||||
memacc_code = decl_code + memacc_code
|
||||
|
||||
@@ -563,9 +564,8 @@ def format StoreUnalignedMemory(memacc_code, ea_code = {{ EA = (Rs + disp) & ~3;
|
||||
uint32_t mem_word = 0;
|
||||
uint32_t unaligned_addr = Rs + disp;
|
||||
uint32_t byte_offset = unaligned_addr & 3;
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
if (GuestByteOrder == BigEndianByteOrder)
|
||||
byte_offset ^= 3;
|
||||
#endif
|
||||
fault = readMemAtomic(xc, traceData, EA, mem_word, memAccessFlags);
|
||||
'''
|
||||
memacc_code = decl_code + memacc_code + '\nMem = mem_word;\n'
|
||||
|
||||
@@ -193,50 +193,51 @@ output exec {{
|
||||
CP0Unimplemented::execute(%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
if (!isCoprocessorEnabled(xc, 0)) {
|
||||
return new CoprocessorUnusableFault(0);
|
||||
}
|
||||
return new ReservedInstructionFault;
|
||||
#else
|
||||
panic("attempt to execute unimplemented instruction '%s' "
|
||||
"(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE,
|
||||
inst2string(machInst));
|
||||
return new UnimplementedOpcodeFault;
|
||||
#endif
|
||||
if (FULL_SYSTEM) {
|
||||
if (!isCoprocessorEnabled(xc, 0))
|
||||
return new CoprocessorUnusableFault(0);
|
||||
else
|
||||
return new ReservedInstructionFault;
|
||||
} else {
|
||||
panic("attempt to execute unimplemented instruction '%s' "
|
||||
"(inst %#08x, opcode %#x, binary:%s)",
|
||||
mnemonic, machInst, OPCODE, inst2string(machInst));
|
||||
return new UnimplementedOpcodeFault;
|
||||
}
|
||||
}
|
||||
|
||||
Fault
|
||||
CP1Unimplemented::execute(%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
if (!isCoprocessorEnabled(xc, 1)) {
|
||||
return new CoprocessorUnusableFault(1);
|
||||
}
|
||||
return new ReservedInstructionFault;
|
||||
#else
|
||||
panic("attempt to execute unimplemented instruction '%s' "
|
||||
"(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE,
|
||||
inst2string(machInst));
|
||||
return new UnimplementedOpcodeFault;
|
||||
#endif
|
||||
if (FULL_SYSTEM) {
|
||||
if (!isCoprocessorEnabled(xc, 1))
|
||||
return new CoprocessorUnusableFault(1);
|
||||
else
|
||||
return new ReservedInstructionFault;
|
||||
} else {
|
||||
panic("attempt to execute unimplemented instruction '%s' "
|
||||
"(inst %#08x, opcode %#x, binary:%s)",
|
||||
mnemonic, machInst, OPCODE, inst2string(machInst));
|
||||
return new UnimplementedOpcodeFault;
|
||||
}
|
||||
}
|
||||
|
||||
Fault
|
||||
CP2Unimplemented::execute(%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
#if FULL_SYSTEM
|
||||
if (!isCoprocessorEnabled(xc, 2)) {
|
||||
return new CoprocessorUnusableFault(2);
|
||||
}
|
||||
return new ReservedInstructionFault;
|
||||
#else
|
||||
panic("attempt to execute unimplemented instruction '%s' "
|
||||
"(inst 0x%08x, opcode 0x%x, binary:%s)", mnemonic, machInst, OPCODE,
|
||||
inst2string(machInst));
|
||||
return new UnimplementedOpcodeFault;
|
||||
#endif
|
||||
if (FULL_SYSTEM) {
|
||||
if (!isCoprocessorEnabled(xc, 2))
|
||||
return new CoprocessorUnusableFault(2);
|
||||
else
|
||||
return new ReservedInstructionFault;
|
||||
} else {
|
||||
panic("attempt to execute unimplemented instruction '%s' "
|
||||
"(inst %#08x, opcode %#x, binary:%s)",
|
||||
mnemonic, machInst, OPCODE, inst2string(machInst));
|
||||
return new UnimplementedOpcodeFault;
|
||||
}
|
||||
}
|
||||
|
||||
Fault
|
||||
|
||||
@@ -75,12 +75,15 @@ output exec {{
|
||||
#include "arch/mips/isa_traits.hh"
|
||||
#include "arch/mips/mt.hh"
|
||||
#include "arch/mips/mt_constants.hh"
|
||||
#include "arch/mips/pagetable.hh"
|
||||
#include "arch/mips/pra_constants.hh"
|
||||
#include "arch/mips/tlb.hh"
|
||||
#include "arch/mips/utility.hh"
|
||||
#if defined(linux)
|
||||
#include <fenv.h>
|
||||
#endif
|
||||
|
||||
#include "base/condcodes.hh"
|
||||
#include "cpu/base.hh"
|
||||
#include "cpu/exetrace.hh"
|
||||
#include "debug/MipsPRA.hh"
|
||||
|
||||
Reference in New Issue
Block a user