diff options
Diffstat (limited to 'src/arch/mips/isa')
-rw-r--r-- | src/arch/mips/isa/decoder.isa | 90 | ||||
-rw-r--r-- | src/arch/mips/isa/formats/control.isa | 126 | ||||
-rwxr-xr-x | src/arch/mips/isa/formats/dsp.isa | 22 | ||||
-rw-r--r-- | src/arch/mips/isa/formats/fp.isa | 17 | ||||
-rw-r--r-- | src/arch/mips/isa/formats/mem.isa | 16 | ||||
-rw-r--r-- | src/arch/mips/isa/formats/unimp.isa | 67 | ||||
-rw-r--r-- | src/arch/mips/isa/includes.isa | 3 |
7 files changed, 138 insertions, 203 deletions
diff --git a/src/arch/mips/isa/decoder.isa b/src/arch/mips/isa/decoder.isa index 2185726df..4ed8c0c0c 100644 --- a/src/arch/mips/isa/decoder.isa +++ b/src/arch/mips/isa/decoder.isa @@ -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 } } } diff --git a/src/arch/mips/isa/formats/control.isa b/src/arch/mips/isa/formats/control.isa index cb5b4372f..7e90ed3e5 100644 --- a/src/arch/mips/isa/formats/control.isa +++ b/src/arch/mips/isa/formats/control.isa @@ -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; - } - - } - 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; + if (!FULL_SYSTEM) + return true; + + 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; } }}; diff --git a/src/arch/mips/isa/formats/dsp.isa b/src/arch/mips/isa/formats/dsp.isa index 7d16b4162..2eeefe806 100755 --- a/src/arch/mips/isa/formats/dsp.isa +++ b/src/arch/mips/isa/formats/dsp.isa @@ -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); } }}; diff --git a/src/arch/mips/isa/formats/fp.isa b/src/arch/mips/isa/formats/fp.isa index 72d87f997..dcea32a36 100644 --- a/src/arch/mips/isa/formats/fp.isa +++ b/src/arch/mips/isa/formats/fp.isa @@ -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; } } diff --git a/src/arch/mips/isa/formats/mem.isa b/src/arch/mips/isa/formats/mem.isa index bc3a2b3ce..22296bc3b 100644 --- a/src/arch/mips/isa/formats/mem.isa +++ b/src/arch/mips/isa/formats/mem.isa @@ -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' diff --git a/src/arch/mips/isa/formats/unimp.isa b/src/arch/mips/isa/formats/unimp.isa index 2cee38a4b..e599510a4 100644 --- a/src/arch/mips/isa/formats/unimp.isa +++ b/src/arch/mips/isa/formats/unimp.isa @@ -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 diff --git a/src/arch/mips/isa/includes.isa b/src/arch/mips/isa/includes.isa index 9c1183839..c9f5da41d 100644 --- a/src/arch/mips/isa/includes.isa +++ b/src/arch/mips/isa/includes.isa @@ -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" |