X86: Implement CPUID with a magical function instead of microcode.
This commit is contained in:
parent
d0a43ce2b2
commit
a76c4b8ca1
10 changed files with 349 additions and 407 deletions
|
@ -86,6 +86,7 @@
|
|||
Import('*')
|
||||
|
||||
if env['TARGET_ISA'] == 'x86':
|
||||
Source('cpuid.cc')
|
||||
Source('emulenv.cc')
|
||||
Source('floatregfile.cc')
|
||||
Source('faults.cc')
|
||||
|
@ -173,7 +174,6 @@ if env['TARGET_ISA'] == 'x86':
|
|||
'general_purpose/load_segment_registers.py',
|
||||
'general_purpose/logical.py',
|
||||
'general_purpose/no_operation.py',
|
||||
'general_purpose/processor_information.py',
|
||||
'general_purpose/rotate_and_shift/__init__.py',
|
||||
'general_purpose/rotate_and_shift/rotate.py',
|
||||
'general_purpose/rotate_and_shift/shift.py',
|
||||
|
|
160
src/arch/x86/cpuid.cc
Normal file
160
src/arch/x86/cpuid.cc
Normal file
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* Copyright (c) 2008 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#include "arch/x86/cpuid.hh"
|
||||
#include "base/bitfield.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
|
||||
namespace X86ISA {
|
||||
enum StandardCpuidFunction {
|
||||
VendorAndLargestStdFunc,
|
||||
FamilyModelStepping,
|
||||
NumStandardCpuidFuncs
|
||||
};
|
||||
|
||||
enum ExtendedCpuidFunctions {
|
||||
VendorAndLargestExtFunc,
|
||||
FamilyModelSteppingBrandFeatures,
|
||||
NameString1,
|
||||
NameString2,
|
||||
NameString3,
|
||||
L1CacheAndTLB,
|
||||
L2L3CacheAndL2TLB,
|
||||
APMInfo,
|
||||
|
||||
/*
|
||||
* The following are defined by the spec but not yet implemented
|
||||
*/
|
||||
/* LongModeAddressSize,
|
||||
// Function 9 is reserved
|
||||
SVMInfo = 10,
|
||||
// Functions 11-24 are reserved
|
||||
TLB1GBPageInfo = 25,
|
||||
PerformanceInfo,*/
|
||||
|
||||
NumExtendedCpuidFuncs
|
||||
};
|
||||
|
||||
static const int vendorStringSize = 13;
|
||||
static const char vendorString[vendorStringSize] = "AuthenticAMD";
|
||||
static const int nameStringSize = 48;
|
||||
static const char nameString[nameStringSize] = "Fake M5 x86_64 CPU";
|
||||
|
||||
uint64_t
|
||||
stringToRegister(const char *str)
|
||||
{
|
||||
uint64_t reg = 0;
|
||||
for (int pos = 3; pos >=0; pos--) {
|
||||
reg <<= 8;
|
||||
reg |= str[pos];
|
||||
}
|
||||
return reg;
|
||||
}
|
||||
|
||||
bool
|
||||
doCpuid(ThreadContext * tc, uint32_t function, CpuidResult &result)
|
||||
{
|
||||
uint16_t family = bits(function, 31, 16);
|
||||
uint16_t funcNum = bits(function, 15, 0);
|
||||
if (family == 0x8000) {
|
||||
// The extended functions
|
||||
switch (funcNum) {
|
||||
case VendorAndLargestExtFunc:
|
||||
assert(vendorStringSize >= 12);
|
||||
result = CpuidResult(
|
||||
NumExtendedCpuidFuncs - 1,
|
||||
stringToRegister(vendorString),
|
||||
stringToRegister(vendorString + 4),
|
||||
stringToRegister(vendorString + 8));
|
||||
break;
|
||||
case FamilyModelSteppingBrandFeatures:
|
||||
result = CpuidResult(0x00020f51, 0x00000405,
|
||||
0xe3d3fbff, 0x00000001);
|
||||
break;
|
||||
case NameString1:
|
||||
case NameString2:
|
||||
case NameString3:
|
||||
{
|
||||
// Zero fill anything beyond the end of the string. This
|
||||
// should go away once the string is a vetted parameter.
|
||||
char cleanName[nameStringSize];
|
||||
memset(cleanName, '\0', nameStringSize);
|
||||
strncpy(cleanName, nameString, nameStringSize);
|
||||
|
||||
int offset = (funcNum - NameString1) * 16;
|
||||
assert(nameStringSize >= offset + 16);
|
||||
result = CpuidResult(
|
||||
stringToRegister(cleanName + offset + 0),
|
||||
stringToRegister(cleanName + offset + 4),
|
||||
stringToRegister(cleanName + offset + 8),
|
||||
stringToRegister(cleanName + offset + 12));
|
||||
}
|
||||
break;
|
||||
case L1CacheAndTLB:
|
||||
result = CpuidResult(0xff08ff08, 0xff20ff20,
|
||||
0x40020140, 0x40020140);
|
||||
break;
|
||||
case L2L3CacheAndL2TLB:
|
||||
result = CpuidResult(0x00000000, 0x42004200,
|
||||
0x00000000, 0x04008140);
|
||||
break;
|
||||
case APMInfo:
|
||||
result = CpuidResult(0x80000018, 0x68747541,
|
||||
0x69746e65, 0x444d4163);
|
||||
break;
|
||||
/* case LongModeAddressSize:
|
||||
case SVMInfo:
|
||||
case TLB1GBPageInfo:
|
||||
case PerformanceInfo:*/
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
} else if(family == 0x0000) {
|
||||
// The standard functions
|
||||
switch (funcNum) {
|
||||
case VendorAndLargestStdFunc:
|
||||
assert(vendorStringSize >= 12);
|
||||
result = CpuidResult(
|
||||
NumStandardCpuidFuncs - 1,
|
||||
stringToRegister(vendorString),
|
||||
stringToRegister(vendorString + 4),
|
||||
stringToRegister(vendorString + 8));
|
||||
break;
|
||||
case FamilyModelStepping:
|
||||
result = CpuidResult(0x00020f51, 0000000405,
|
||||
0xe3d3fbff, 0x00000001);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} //namespace X86ISA
|
61
src/arch/x86/cpuid.hh
Normal file
61
src/arch/x86/cpuid.hh
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2008 The Regents of The University of Michigan
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Gabe Black
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_X86_CPUID_HH__
|
||||
#define __ARCH_X86_CPUID_HH__
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
class ThreadContext;
|
||||
|
||||
namespace X86ISA
|
||||
{
|
||||
struct CpuidResult
|
||||
{
|
||||
uint64_t rax;
|
||||
uint64_t rbx;
|
||||
uint64_t rcx;
|
||||
uint64_t rdx;
|
||||
|
||||
// These are not in alphebetical order on purpose. The order reflects
|
||||
// how the CPUID orders the registers when it returns results.
|
||||
CpuidResult(uint64_t _rax, uint64_t _rbx,
|
||||
uint64_t _rdx, uint64_t _rcx) :
|
||||
rax(_rax), rbx(_rbx), rcx(_rcx), rdx(_rdx)
|
||||
{}
|
||||
|
||||
CpuidResult()
|
||||
{}
|
||||
};
|
||||
|
||||
bool doCpuid(ThreadContext * tc, uint32_t function, CpuidResult &result);
|
||||
} // namespace X86ISA
|
||||
|
||||
#endif
|
|
@ -168,7 +168,7 @@
|
|||
#if FULL_SYSTEM
|
||||
0x05: syscall();
|
||||
#else
|
||||
0x05: SyscallInst::syscall('xc->syscall(rax)', IsSyscall);
|
||||
0x05: SyscallInst::syscall('xc->syscall(Rax)', IsSyscall);
|
||||
#endif
|
||||
0x06: clts();
|
||||
//sandpile.org says (AMD) after sysret, so I might want to check
|
||||
|
@ -707,7 +707,14 @@
|
|||
0x14: decode OPCODE_OP_BOTTOM3 {
|
||||
0x0: push_fs();
|
||||
0x1: pop_fs();
|
||||
0x2: Inst::CPUID(rAd);
|
||||
0x2: CPUIDInst::CPUID({{
|
||||
CpuidResult result;
|
||||
success = doCpuid(xc->tcBase(), Rax, result);
|
||||
Rax = result.rax;
|
||||
Rbx = result.rbx;
|
||||
Rcx = result.rcx;
|
||||
Rdx = result.rdx;
|
||||
}});
|
||||
0x3: Inst::BT(Ev,Gv);
|
||||
0x4: shld_Ev_Gv_Ib();
|
||||
0x5: shld_Ev_Gv_rCl();
|
||||
|
|
110
src/arch/x86/isa/formats/cpuid.isa
Normal file
110
src/arch/x86/isa/formats/cpuid.isa
Normal file
|
@ -0,0 +1,110 @@
|
|||
// Copyright (c) 2008 The Hewlett-Packard Development Company
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use of this software in source and binary forms,
|
||||
// with or without modification, are permitted provided that the
|
||||
// following conditions are met:
|
||||
//
|
||||
// The software must be used only for Non-Commercial Use which means any
|
||||
// use which is NOT directed to receiving any direct monetary
|
||||
// compensation for, or commercial advantage from such use. Illustrative
|
||||
// examples of non-commercial use are academic research, personal study,
|
||||
// teaching, education and corporate research & development.
|
||||
// Illustrative examples of commercial use are distributing products for
|
||||
// commercial advantage and providing services using the software for
|
||||
// commercial advantage.
|
||||
//
|
||||
// If you wish to use this software or functionality therein that may be
|
||||
// covered by patents for commercial use, please contact:
|
||||
// Director of Intellectual Property Licensing
|
||||
// Office of Strategy and Technology
|
||||
// Hewlett-Packard Company
|
||||
// 1501 Page Mill Road
|
||||
// Palo Alto, California 94304
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer. Redistributions
|
||||
// in binary form must reproduce the above copyright notice, this list of
|
||||
// conditions and the following disclaimer in the documentation and/or
|
||||
// other materials provided with the distribution. Neither the name of
|
||||
// the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission. No right of
|
||||
// sublicense is granted herewith. Derivatives of the software and
|
||||
// output created using the software may be prepared, but only for
|
||||
// Non-Commercial Uses. Derivatives of the software may be shared with
|
||||
// others provided: (i) the others agree to abide by the list of
|
||||
// conditions herein which includes the Non-Commercial Use restrictions;
|
||||
// and (ii) such Derivatives of the software include the above copyright
|
||||
// notice to acknowledge the contribution from this software where
|
||||
// applicable, this list of conditions and the disclaimer below.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
// Authors: Gabe Black
|
||||
|
||||
output header {{
|
||||
class CPUIDInst : public X86ISA::X86StaticInst
|
||||
{
|
||||
public:
|
||||
static const RegIndex foldOBit = 0;
|
||||
/// Constructor
|
||||
CPUIDInst(const char *_mnemonic, ExtMachInst _machInst,
|
||||
OpClass __opClass) :
|
||||
X86ISA::X86StaticInst(_mnemonic, _machInst, __opClass)
|
||||
{
|
||||
}
|
||||
|
||||
std::string generateDisassembly(Addr pc,
|
||||
const SymbolTable *symtab) const;
|
||||
};
|
||||
}};
|
||||
|
||||
output decoder {{
|
||||
std::string CPUIDInst::generateDisassembly(Addr PC,
|
||||
const SymbolTable *symtab) const
|
||||
{
|
||||
std::stringstream response;
|
||||
|
||||
printMnemonic(response, mnemonic);
|
||||
ccprintf(response, " ");
|
||||
printReg(response, _srcRegIdx[0], machInst.opSize);
|
||||
return response.str();
|
||||
}
|
||||
}};
|
||||
|
||||
def template CPUIDExecute {{
|
||||
Fault %(class_name)s::execute(%(CPU_exec_context)s *xc,
|
||||
Trace::InstRecord *traceData) const
|
||||
{
|
||||
// If the CPUID instruction used a valid function number, this will
|
||||
// be set to true. Otherwise, the instruction does nothing.
|
||||
bool success;
|
||||
%(op_decl)s;
|
||||
%(op_rd)s;
|
||||
%(code)s;
|
||||
if (success) {
|
||||
%(op_wb)s;
|
||||
}
|
||||
return NoFault;
|
||||
}
|
||||
}};
|
||||
|
||||
def format CPUIDInst(code, *opt_flags) {{
|
||||
iop = InstObjParams(name, Name, 'CPUIDInst', code, opt_flags)
|
||||
header_output = BasicDeclare.subst(iop)
|
||||
decoder_output = BasicConstructor.subst(iop)
|
||||
decode_block = BasicDecode.subst(iop)
|
||||
exec_output = CPUIDExecute.subst(iop)
|
||||
}};
|
||||
|
|
@ -85,6 +85,9 @@
|
|||
//Templates from this format are used later
|
||||
##include "basic.isa"
|
||||
|
||||
//Include a format to generate a CPUID instruction.
|
||||
##include "cpuid.isa"
|
||||
|
||||
//Include the "unknown" format
|
||||
##include "unknown.isa"
|
||||
|
||||
|
|
|
@ -145,6 +145,7 @@ output exec {{
|
|||
#include <limits>
|
||||
|
||||
#include <cmath>
|
||||
#include "arch/x86/cpuid.hh"
|
||||
#include "arch/x86/miscregs.hh"
|
||||
#include "arch/x86/tlb.hh"
|
||||
#include "base/bigint.hh"
|
||||
|
|
|
@ -65,7 +65,6 @@ categories = ["arithmetic",
|
|||
"load_segment_registers",
|
||||
"logical",
|
||||
"no_operation",
|
||||
"processor_information",
|
||||
"rotate_and_shift",
|
||||
"semaphores",
|
||||
"string",
|
||||
|
|
|
@ -1,402 +0,0 @@
|
|||
# Copyright (c) 2007-2008 The Hewlett-Packard Development Company
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use of this software in source and binary forms,
|
||||
# with or without modification, are permitted provided that the
|
||||
# following conditions are met:
|
||||
#
|
||||
# The software must be used only for Non-Commercial Use which means any
|
||||
# use which is NOT directed to receiving any direct monetary
|
||||
# compensation for, or commercial advantage from such use. Illustrative
|
||||
# examples of non-commercial use are academic research, personal study,
|
||||
# teaching, education and corporate research & development.
|
||||
# Illustrative examples of commercial use are distributing products for
|
||||
# commercial advantage and providing services using the software for
|
||||
# commercial advantage.
|
||||
#
|
||||
# If you wish to use this software or functionality therein that may be
|
||||
# covered by patents for commercial use, please contact:
|
||||
# Director of Intellectual Property Licensing
|
||||
# Office of Strategy and Technology
|
||||
# Hewlett-Packard Company
|
||||
# 1501 Page Mill Road
|
||||
# Palo Alto, California 94304
|
||||
#
|
||||
# Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer. Redistributions
|
||||
# in binary form must reproduce the above copyright notice, this list of
|
||||
# conditions and the following disclaimer in the documentation and/or
|
||||
# other materials provided with the distribution. Neither the name of
|
||||
# the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission. No right of
|
||||
# sublicense is granted herewith. Derivatives of the software and
|
||||
# output created using the software may be prepared, but only for
|
||||
# Non-Commercial Uses. Derivatives of the software may be shared with
|
||||
# others provided: (i) the others agree to abide by the list of
|
||||
# conditions herein which includes the Non-Commercial Use restrictions;
|
||||
# and (ii) such Derivatives of the software include the above copyright
|
||||
# notice to acknowledge the contribution from this software where
|
||||
# applicable, this list of conditions and the disclaimer below.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Authors: Gabe Black
|
||||
|
||||
microcode = '''
|
||||
def macroop CPUID_R {
|
||||
|
||||
#
|
||||
# Find which type of cpuid function it is by checking bit 31. Also clear that
|
||||
# bit to form an offset into the functions of that type.
|
||||
#
|
||||
limm t1, 0x80000000, dataSize=4
|
||||
and t2, t1, rax, flags=(EZF,)
|
||||
# clear the bit
|
||||
xor t1, t2, rax
|
||||
|
||||
#
|
||||
# Do range checking on the offset
|
||||
#
|
||||
# If EZF is set, the function is standard and the max is 0x1.
|
||||
movi t2, t2, 0x1, flags=(CEZF,)
|
||||
# If EZF is cleared, the function is extended and the max is 0x18.
|
||||
movi t2, t2, 0x18, flags=(nCEZF,)
|
||||
subi t0, t1, t2, flags=(ECF,)
|
||||
# ECF will be set if the offset is too large.
|
||||
bri t0, label("end"), flags=(nCECF,)
|
||||
|
||||
|
||||
#
|
||||
# Jump to the right portion
|
||||
#
|
||||
movi t2, t2, label("standardStart"), flags=(CEZF,)
|
||||
movi t2, t2, label("extendedStart"), flags=(nCEZF,)
|
||||
# This gives each function 8 microops to use. It's wasteful because only
|
||||
# 5 will be needed, but a multiply would be expensive. In the system
|
||||
# described in the RISC86 patent, the fifth instruction would really be
|
||||
# the sequencing field on an op quad, so each function would be implemented
|
||||
# by -exactly- one op quad. Since we're approximating, this should be ok.
|
||||
slli t1, t1, 3
|
||||
br t2, t1
|
||||
|
||||
#############################################################################
|
||||
#############################################################################
|
||||
|
||||
#
|
||||
# Standard functions.
|
||||
#
|
||||
|
||||
standardStart:
|
||||
|
||||
# 0x00000000 -- Processor Vendor and Largest Standard Function Number
|
||||
limm rax, 0x00000001, dataSize=4
|
||||
limm rbx, 0x68747541, dataSize=4
|
||||
limm rdx, 0x69746e65, dataSize=4
|
||||
limm rcx, 0x444d4163, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
# 0x00000001 -- Family, Model, Stepping Identifiers
|
||||
limm rax, 0x00020f51, dataSize=4
|
||||
limm rbx, 0x00000405, dataSize=4
|
||||
limm rdx, 0xe3d3fbff, dataSize=4
|
||||
limm rcx, 0x00000001, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
#
|
||||
# Extended functions.
|
||||
#
|
||||
|
||||
extendedStart:
|
||||
|
||||
# 0x80000000 -- Processor Vendor and Largest Extended Function Number
|
||||
limm rax, 0x80000018, dataSize=4
|
||||
limm rbx, 0x68747541, dataSize=4
|
||||
limm rdx, 0x69746e65, dataSize=4
|
||||
limm rcx, 0x444d4163, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
# 0x80000001 -- EAX: AMD Family, Model, Stepping
|
||||
# EBX: BrandId Identifier
|
||||
# ECX: Feature Identifiers
|
||||
# EDX: Feature Identifiers
|
||||
limm rax, 0x00020f51, dataSize=4
|
||||
limm rbx, 0x00000405, dataSize=4
|
||||
limm rdx, 0xe3d3fbff, dataSize=4
|
||||
limm rcx, 0x00000001, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
# 0x80000002 -- Processor Name String Identifier
|
||||
limm rax, 0x656B6146, dataSize=4
|
||||
limm rbx, 0x20354D20, dataSize=4
|
||||
limm rcx, 0x5F363878, dataSize=4
|
||||
limm rdx, 0x43203436, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
# 0x80000003 -- Processor Name String Identifier
|
||||
limm rax, 0x00005550, dataSize=4
|
||||
limm rbx, 0x00000000, dataSize=4
|
||||
limm rdx, 0x00000000, dataSize=4
|
||||
limm rcx, 0x00000000, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
# 0x80000004 -- Processor Name String Identifier
|
||||
limm rax, 0x00000000, dataSize=4
|
||||
limm rbx, 0x00000000, dataSize=4
|
||||
limm rdx, 0x00000000, dataSize=4
|
||||
limm rcx, 0x00000000, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
# 0x80000005 -- L1 Cache and TLB Identifiers
|
||||
limm rax, 0xff08ff08, dataSize=4
|
||||
limm rbx, 0xff20ff20, dataSize=4
|
||||
limm rdx, 0x40020140, dataSize=4
|
||||
limm rcx, 0x40020140, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
# 0x80000006 -- L2/L3 Cache and L2 TLB Identifiers
|
||||
limm rax, 0x00000000, dataSize=4
|
||||
limm rbx, 0x42004200, dataSize=4
|
||||
limm rdx, 0x00000000, dataSize=4
|
||||
limm rcx, 0x04008140, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
# 0x80000007 -- Advanced Power Management Information
|
||||
# JUNK VALUES
|
||||
limm rax, 0x80000018, dataSize=4
|
||||
limm rbx, 0x68747541, dataSize=4
|
||||
limm rdx, 0x69746e65, dataSize=4
|
||||
limm rcx, 0x444d4163, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
# 0x80000008 -- Long Mode Address Size Identification
|
||||
# JUNK VALUES
|
||||
limm rax, 0x80000018, dataSize=4
|
||||
limm rbx, 0x68747541, dataSize=4
|
||||
limm rdx, 0x69746e65, dataSize=4
|
||||
limm rcx, 0x444d4163, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
# 0x80000009 -- Reserved
|
||||
# JUNK VALUES
|
||||
limm rax, 0x80000018, dataSize=4
|
||||
limm rbx, 0x68747541, dataSize=4
|
||||
limm rdx, 0x69746e65, dataSize=4
|
||||
limm rcx, 0x444d4163, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
# 0x8000000A -- SVM Revision and Feature Identification
|
||||
# JUNK VALUES
|
||||
limm rax, 0x80000018, dataSize=4
|
||||
limm rbx, 0x68747541, dataSize=4
|
||||
limm rdx, 0x69746e65, dataSize=4
|
||||
limm rcx, 0x444d4163, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
# 0x8000000B -- Reserved
|
||||
# JUNK VALUES
|
||||
limm rax, 0x80000018, dataSize=4
|
||||
limm rbx, 0x68747541, dataSize=4
|
||||
limm rdx, 0x69746e65, dataSize=4
|
||||
limm rcx, 0x444d4163, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
# 0x8000000C -- Reserved
|
||||
# JUNK VALUES
|
||||
limm rax, 0x80000018, dataSize=4
|
||||
limm rbx, 0x68747541, dataSize=4
|
||||
limm rdx, 0x69746e65, dataSize=4
|
||||
limm rcx, 0x444d4163, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
# 0x8000000D -- Reserved
|
||||
# JUNK VALUES
|
||||
limm rax, 0x80000018, dataSize=4
|
||||
limm rbx, 0x68747541, dataSize=4
|
||||
limm rdx, 0x69746e65, dataSize=4
|
||||
limm rcx, 0x444d4163, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
# 0x8000000E -- Reserved
|
||||
# JUNK VALUES
|
||||
limm rax, 0x80000018, dataSize=4
|
||||
limm rbx, 0x68747541, dataSize=4
|
||||
limm rdx, 0x69746e65, dataSize=4
|
||||
limm rcx, 0x444d4163, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
# 0x8000000F -- Reserved
|
||||
# JUNK VALUES
|
||||
limm rax, 0x80000018, dataSize=4
|
||||
limm rbx, 0x68747541, dataSize=4
|
||||
limm rdx, 0x69746e65, dataSize=4
|
||||
limm rcx, 0x444d4163, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
# 0x80000010 -- Reserved
|
||||
# JUNK VALUES
|
||||
limm rax, 0x80000018, dataSize=4
|
||||
limm rbx, 0x68747541, dataSize=4
|
||||
limm rdx, 0x69746e65, dataSize=4
|
||||
limm rcx, 0x444d4163, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
# 0x80000011 -- Reserved
|
||||
# JUNK VALUES
|
||||
limm rax, 0x80000018, dataSize=4
|
||||
limm rbx, 0x68747541, dataSize=4
|
||||
limm rdx, 0x69746e65, dataSize=4
|
||||
limm rcx, 0x444d4163, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
# 0x80000012 -- Reserved
|
||||
# JUNK VALUES
|
||||
limm rax, 0x80000018, dataSize=4
|
||||
limm rbx, 0x68747541, dataSize=4
|
||||
limm rdx, 0x69746e65, dataSize=4
|
||||
limm rcx, 0x444d4163, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
# 0x80000013 -- Reserved
|
||||
# JUNK VALUES
|
||||
limm rax, 0x80000018, dataSize=4
|
||||
limm rbx, 0x68747541, dataSize=4
|
||||
limm rdx, 0x69746e65, dataSize=4
|
||||
limm rcx, 0x444d4163, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
# 0x80000014 -- Reserved
|
||||
# JUNK VALUES
|
||||
limm rax, 0x80000018, dataSize=4
|
||||
limm rbx, 0x68747541, dataSize=4
|
||||
limm rdx, 0x69746e65, dataSize=4
|
||||
limm rcx, 0x444d4163, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
# 0x80000015 -- Reserved
|
||||
# JUNK VALUES
|
||||
limm rax, 0x80000018, dataSize=4
|
||||
limm rbx, 0x68747541, dataSize=4
|
||||
limm rdx, 0x69746e65, dataSize=4
|
||||
limm rcx, 0x444d4163, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
# 0x80000016 -- Reserved
|
||||
# JUNK VALUES
|
||||
limm rax, 0x80000018, dataSize=4
|
||||
limm rbx, 0x68747541, dataSize=4
|
||||
limm rdx, 0x69746e65, dataSize=4
|
||||
limm rcx, 0x444d4163, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
# 0x80000017 -- Reserved
|
||||
# JUNK VALUES
|
||||
limm rax, 0x80000018, dataSize=4
|
||||
limm rbx, 0x68747541, dataSize=4
|
||||
limm rdx, 0x69746e65, dataSize=4
|
||||
limm rcx, 0x444d4163, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
# 0x80000018 -- Reserved
|
||||
# JUNK VALUES
|
||||
limm rax, 0x80000018, dataSize=4
|
||||
limm rbx, 0x68747541, dataSize=4
|
||||
limm rdx, 0x69746e65, dataSize=4
|
||||
limm rcx, 0x444d4163, dataSize=4
|
||||
bri t0, label("end")
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
fault "NoFault"
|
||||
|
||||
end:
|
||||
fault "NoFault"
|
||||
};
|
||||
'''
|
|
@ -109,7 +109,10 @@ def operands {{
|
|||
'Quotient': ('IntReg', 'uqw', 'INTREG_IMPLICIT(2)', 'IsInteger', 9),
|
||||
'Remainder': ('IntReg', 'uqw', 'INTREG_IMPLICIT(3)', 'IsInteger', 10),
|
||||
'Divisor': ('IntReg', 'uqw', 'INTREG_IMPLICIT(4)', 'IsInteger', 11),
|
||||
'rax': ('IntReg', 'uqw', '(INTREG_RAX)', 'IsInteger', 12),
|
||||
'Rax': ('IntReg', 'uqw', '(INTREG_RAX)', 'IsInteger', 12),
|
||||
'Rbx': ('IntReg', 'uqw', '(INTREG_RBX)', 'IsInteger', 13),
|
||||
'Rcx': ('IntReg', 'uqw', '(INTREG_RCX)', 'IsInteger', 14),
|
||||
'Rdx': ('IntReg', 'uqw', '(INTREG_RDX)', 'IsInteger', 15),
|
||||
'FpSrcReg1': ('FloatReg', 'df', 'src1', 'IsFloating', 20),
|
||||
'FpSrcReg2': ('FloatReg', 'df', 'src2', 'IsFloating', 21),
|
||||
'FpDestReg': ('FloatReg', 'df', 'dest', 'IsFloating', 22),
|
||||
|
|
Loading…
Reference in a new issue