mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-21 19:42:14 +00:00
Moved HCS12 files for release.
This commit is contained in:
parent
f5a366fa5c
commit
a744c01b6d
0
Ghidra/Processors/HCS12/Module.manifest
Normal file
0
Ghidra/Processors/HCS12/Module.manifest
Normal file
5
Ghidra/Processors/HCS12/build.gradle
Normal file
5
Ghidra/Processors/HCS12/build.gradle
Normal file
@ -0,0 +1,5 @@
|
||||
apply from: "$rootProject.projectDir/gradle/distributableGhidraModule.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/processorProject.gradle"
|
||||
apply plugin: 'eclipse'
|
||||
eclipse.project.name = 'Processors HCS12'
|
||||
|
13
Ghidra/Processors/HCS12/certification.manifest
Normal file
13
Ghidra/Processors/HCS12/certification.manifest
Normal file
@ -0,0 +1,13 @@
|
||||
##VERSION: 2.0
|
||||
.project||NONE||||END|
|
||||
Module.manifest||GHIDRA||||END|
|
||||
build.gradle||GHIDRA||||END|
|
||||
data/build.xml||GHIDRA||||END|
|
||||
data/languages/HCS12.cspec||GHIDRA||||END|
|
||||
data/languages/HCS12.ldefs||GHIDRA||||END|
|
||||
data/languages/HCS12.opinion||GHIDRA||||END|
|
||||
data/languages/HCS12.pspec||GHIDRA||||END|
|
||||
data/languages/HCS12.slaspec||GHIDRA||||END|
|
||||
data/languages/HCS_HC12.sinc||GHIDRA||||END|
|
||||
data/languages/XGATE.sinc||GHIDRA||||END|
|
||||
data/manuals/HCS12.idx||GHIDRA||||END|
|
143
Ghidra/Processors/HCS12/data/languages/HCS12.cspec
Normal file
143
Ghidra/Processors/HCS12/data/languages/HCS12.cspec
Normal file
@ -0,0 +1,143 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<compiler_spec>
|
||||
<data_organization> <!-- These tags need to be verified -->
|
||||
<absolute_max_alignment value="0" />
|
||||
<machine_alignment value="1" />
|
||||
<default_alignment value="1" />
|
||||
<default_pointer_alignment value="3" />
|
||||
<pointer_size value="2" />
|
||||
<wchar_size value="4" />
|
||||
<short_size value="2" />
|
||||
<integer_size value="4" />
|
||||
<long_size value="4" />
|
||||
<long_long_size value="8" />
|
||||
<float_size value="4" />
|
||||
<double_size value="8" />
|
||||
<long_double_size value="8" />
|
||||
<size_alignment_map>
|
||||
<entry size="1" alignment="1" />
|
||||
<entry size="2" alignment="2" />
|
||||
<entry size="4" alignment="4" />
|
||||
<entry size="8" alignment="8" />
|
||||
</size_alignment_map>
|
||||
</data_organization>
|
||||
|
||||
<global>
|
||||
<range space="RAM" first="0x00" last="0x0f"/>
|
||||
<range space="RAM" first="0x11" last="0x15"/>
|
||||
<range space="RAM" first="0x18" last="0x2f"/>
|
||||
<range space="RAM" first="0x31" last="0xffff"/>
|
||||
</global>
|
||||
<stackpointer register="SP" space="RAM" growth="negative"/>
|
||||
<segmentop space="RAM" userop="segment" baseinsize="1" innerinsize="2" farpointer="no">
|
||||
<baseop code="INT_ZEXT"/>
|
||||
<baseop code="INT_LEFT" value="16"/>
|
||||
<innerop code="INT_ZEXT"/>
|
||||
<constresolve>
|
||||
<register name="PPAGE"/>
|
||||
</constresolve>
|
||||
</segmentop>
|
||||
<returnaddress>
|
||||
<varnode space="stack" offset="0" size="3"/>
|
||||
</returnaddress>
|
||||
<default_proto>
|
||||
<prototype name="__asmA" extrapop="2" stackshift="2" strategy="register">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="1">
|
||||
<register name="A"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="1">
|
||||
<register name="B"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="2">
|
||||
<register name="D"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="2">
|
||||
<register name="IY"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="2">
|
||||
<register name="IX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="2">
|
||||
<addr offset="2" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="2">
|
||||
<register name="D"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="SP"/>
|
||||
<register name="PPAGE"/>
|
||||
<register name="RPAGE"/>
|
||||
<register name="GPAGE"/>
|
||||
</unaffected>
|
||||
</prototype>
|
||||
</default_proto>
|
||||
|
||||
<prototype name="__asmA_longcall" extrapop="3" stackshift="3" strategy="register">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="1">
|
||||
<register name="A"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="1">
|
||||
<register name="B"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="2">
|
||||
<register name="D"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="2">
|
||||
<register name="IY"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="2">
|
||||
<register name="IX"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="2">
|
||||
<addr offset="2" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="2">
|
||||
<register name="D"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<register name="SP"/>
|
||||
<register name="PPAGE"/>
|
||||
<register name="RPAGE"/>
|
||||
<register name="GPAGE"/>
|
||||
</unaffected>
|
||||
</prototype>
|
||||
<prototype name="__asmA_xgate" extrapop="3" stackshift="3" strategy="register">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="2">
|
||||
<register name="R2"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="2">
|
||||
<register name="R3"/>
|
||||
</pentry>
|
||||
<pentry minsize="3" maxsize="4">
|
||||
<addr space="join" piece1="R2" piece2="R3"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="2">
|
||||
<register name="R4"/>
|
||||
</pentry>
|
||||
<pentry minsize="3" maxsize="4">
|
||||
<addr space="join" piece1="R3" piece2="R4"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="500" align="2">
|
||||
<addr offset="2" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="2">
|
||||
<register name="R2"/>
|
||||
</pentry>
|
||||
<pentry minsize="4" maxsize="4">
|
||||
<addr space="join" piece1="R2" piece2="R3"/>
|
||||
</pentry>
|
||||
</output>
|
||||
</prototype>
|
||||
</compiler_spec>
|
17
Ghidra/Processors/HCS12/data/languages/HCS12.ldefs
Normal file
17
Ghidra/Processors/HCS12/data/languages/HCS12.ldefs
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<language_definitions>
|
||||
<language processor="HCS12"
|
||||
endian="big"
|
||||
size="24"
|
||||
variant="default"
|
||||
version="1.0"
|
||||
slafile="HCS12.sla"
|
||||
processorspec="HCS12.pspec"
|
||||
manualindexfile="../manuals/HCS12.idx"
|
||||
id="HCS12:BE:24:default">
|
||||
<description>HCS12X Microcontroller Family</description>
|
||||
<compiler name="default" spec="HCS12.cspec" id="default"/>
|
||||
<external_name tool="gnu" name="m9s12x"/>
|
||||
</language>
|
||||
</language_definitions>
|
6
Ghidra/Processors/HCS12/data/languages/HCS12.opinion
Normal file
6
Ghidra/Processors/HCS12/data/languages/HCS12.opinion
Normal file
@ -0,0 +1,6 @@
|
||||
<opinions>
|
||||
<constraint loader="Executable and Linking Format (ELF)" compilerSpecID="default">
|
||||
<constraint primary="53" processor="HCS12" endian="big" size="24" variant="default"/>
|
||||
</constraint>
|
||||
</opinions>
|
||||
|
87
Ghidra/Processors/HCS12/data/languages/HCS12.pspec
Normal file
87
Ghidra/Processors/HCS12/data/languages/HCS12.pspec
Normal file
@ -0,0 +1,87 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
This is the processor specification for the MC9S12C and MC9S12GC processor families.
|
||||
It is based upon the MC9S12C128 and MC9S12GC128 variants.
|
||||
-->
|
||||
<processor_spec>
|
||||
<programcounter register="PC"/>
|
||||
<!-- TODO
|
||||
<volatile outputop="write_volatile" inputop="read_volatile">
|
||||
<range space="RAM" first="0x0" last="0x03FF"/>
|
||||
</volatile>
|
||||
-->
|
||||
<context_data>
|
||||
<tracked_set space="RAM">
|
||||
<set name="PPAGE" val="0xfe"/>
|
||||
<set name="RPAGE" val="0xfd"/>
|
||||
<set name="EPAGE" val="0xfe"/>
|
||||
<set name="XG_BASE" val="0xfe800"/>
|
||||
</tracked_set>
|
||||
</context_data>
|
||||
<default_symbols>
|
||||
<symbol name="VECTOR_Reset" address="FFFE" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_ClockMonitorFailReset" address="FFFC" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_COPFailureReset" address="FFFA" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_UnimplementedInstructionTrap" address="FFF8" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_SWI" address="FFF6" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_XIRQ" address="FFF4" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_IRQ" address="FFF2" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_RealTimeInterrupt" address="FFF0" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_StandardTimerChannel0" address="FFEE" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_StandardTimerChannel1" address="FFEC" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_StandardTimerChannel2" address="FFEA" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_StandardTimerChannel3" address="FFE8" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_StandardTimerChannel4" address="FFE6" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_StandardTimerChannel5" address="FFE4" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_StandardTimerChannel6" address="FFE2" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_StandardTimerChannel7" address="FFE0" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_StandardTimerOverflow" address="FFDE" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_PulseAccumulatorAOverflow" address="FFDC" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_PulseAccumulatorInputEdge" address="FFDA" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_SPI" address="FFD8" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_SCI" address="FFD6" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FFD4" address="FFD4" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_ATD" address="FFD2" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FFD0" address="FFD0" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_PortJ" address="FFCE" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FFCC" address="FFCC" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FFCA" address="FFCA" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FFC8" address="FFC8" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_CRG_PLL_Lock" address="FFC6" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_CRGSelfClockMode" address="FFC4" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FFC2" address="FFC2" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FFC0" address="FFC0" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FFBE" address="FFBE" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FFBC" address="FFBC" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FFBA" address="FFBA" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_FLASH" address="FFB8" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_CANwake-up" address="FFB6" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_CANerrors" address="FFB4" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_CANreceive" address="FFB2" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_CANtransmit" address="FFB0" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FFAE" address="FFAE" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FFAC" address="FFAC" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FFAA" address="FFAA" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FFA8" address="FFA8" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FFA6" address="FFA6" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FFA4" address="FFA4" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FFA2" address="FFA2" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FFA0" address="FFA0" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FF9E" address="FF9E" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FF9C" address="FF9C" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FF9A" address="FF9A" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FF98" address="FF98" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FF96" address="FF96" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FF94" address="FF94" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FF92" address="FF92" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FF90" address="FF90" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_PortP" address="FF8E" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_PWM_EmergencyShutdown" address="FF8C" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_VREG_LVI" address="FF8A" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FF88" address="FF88" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FF86" address="FF86" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FF84" address="FF84" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FF82" address="FF82" entry="true" type="code_ptr"/>
|
||||
<symbol name="VECTOR_Reserved_FF80" address="FF80" entry="true" type="code_ptr"/>
|
||||
</default_symbols>
|
||||
</processor_spec>
|
9
Ghidra/Processors/HCS12/data/languages/HCS12.slaspec
Normal file
9
Ghidra/Processors/HCS12/data/languages/HCS12.slaspec
Normal file
@ -0,0 +1,9 @@
|
||||
# sleigh specification file for Freescale HCS12 (68HCS12)
|
||||
|
||||
@define HCS12 "1"
|
||||
@define HCS12X "1"
|
||||
|
||||
@define MAXFLASHPage "0xFF"
|
||||
|
||||
@include "HCS_HC12.sinc"
|
||||
@include "XGATE.sinc"
|
5708
Ghidra/Processors/HCS12/data/languages/HCS_HC12.sinc
Normal file
5708
Ghidra/Processors/HCS12/data/languages/HCS_HC12.sinc
Normal file
File diff suppressed because it is too large
Load Diff
960
Ghidra/Processors/HCS12/data/languages/XGATE.sinc
Normal file
960
Ghidra/Processors/HCS12/data/languages/XGATE.sinc
Normal file
@ -0,0 +1,960 @@
|
||||
# sleigh specification file for XGATE MCU peripheral co-processor
|
||||
|
||||
################################################################
|
||||
# Registers
|
||||
################################################################
|
||||
|
||||
# register R0 always contains the value 0
|
||||
define register offset=0x100 size=2 [R0 R1 R2 R3 R4 R5 R6 R7];
|
||||
define register offset=0x110 size=2 [XPC XCCR];
|
||||
define register offset=0x120 size=1 [XC XV XZ XN];
|
||||
define register offset=0x130 size=3 [XG_BASE];
|
||||
|
||||
# Individual status bits within the XCCR
|
||||
@define XN "XN" # XCCR[3,1] # Negative Flag
|
||||
@define XZ "XZ" # XCCR[2,1] # Zero Flag
|
||||
@define XV "XV" # XCCR[1,1] # Overflow Flag
|
||||
@define XC "XC" # XCCR[0,1] # Carry Flag
|
||||
|
||||
################################################################
|
||||
# Tokens
|
||||
################################################################
|
||||
define token XOpWord16 (16)
|
||||
xop16 = (0,15)
|
||||
opcode = (11,15)
|
||||
reg8 = (8,10)
|
||||
reg8_lo = (8,10)
|
||||
reg8_hi = (8,10)
|
||||
imm3 = (8,10)
|
||||
op9_10 = (9,10)
|
||||
bit_10 = (10,10)
|
||||
immrel9 = (0,9) signed
|
||||
immrel8 = (0,8) signed
|
||||
xop8 = (0,7)
|
||||
reg5 = (5,7)
|
||||
ximm4 = (4,7)
|
||||
ximm8 = (0,7)
|
||||
op4 = (0,4)
|
||||
op3 = (0,3)
|
||||
offs5 = (0,5)
|
||||
reg2 = (2,4)
|
||||
op2 = (0,1)
|
||||
;
|
||||
|
||||
################################################################
|
||||
# Attach variables
|
||||
################################################################
|
||||
|
||||
attach variables [reg8 reg5 reg2] [R0 R1 R2 R3 R4 R5 R6 R7];
|
||||
|
||||
################################################################
|
||||
# Pseudo Instructions
|
||||
################################################################
|
||||
define pcodeop bfins;
|
||||
define pcodeop bfinsi;
|
||||
define pcodeop findFirstOne;
|
||||
define pcodeop leftShiftCarry;
|
||||
define pcodeop rightShiftCarry;
|
||||
define pcodeop parity;
|
||||
define pcodeop clearSemaphore;
|
||||
define pcodeop setSemaphore;
|
||||
define pcodeop setInterruptFlag;
|
||||
|
||||
################################################################
|
||||
# Macros Instructions
|
||||
################################################################
|
||||
|
||||
macro default_flags(result)
|
||||
{
|
||||
$(XZ) = (result == 0);
|
||||
$(XN) = (result s< 0);
|
||||
$(XV) = 0;
|
||||
#$(XC) not affected
|
||||
}
|
||||
|
||||
macro default_flagsH(result)
|
||||
{
|
||||
$(XN) = (result s< 0);
|
||||
$(XZ) = ((result & 0xff00) == 0);
|
||||
$(XV) = 0;
|
||||
#$(XC) not affected
|
||||
}
|
||||
|
||||
macro default_flagsL(result)
|
||||
{
|
||||
$(XN) = ((result & 0x0080) != 0);
|
||||
$(XZ) = ((result & 0xff) == 0);
|
||||
$(XV) = 0;
|
||||
#$(XC) not affected
|
||||
}
|
||||
|
||||
macro addition_flags(operand1, operand2, result)
|
||||
{
|
||||
$(XN) = (result s< 0);
|
||||
$(XZ) = ((result == 0) & ($(XZ)==1));
|
||||
$(XV) = (((operand1 & operand2 & ~result) | (~operand1 & ~operand2 & result)) & 0x8000) != 0;
|
||||
$(XC) = (((operand1 & operand2) | (operand2 & ~result) | (~result & operand1)) & 0x8000) != 0;
|
||||
}
|
||||
|
||||
macro subtraction_flags(register, operand, result) {
|
||||
$(XN) = (result s< 0);
|
||||
$(XZ) = (result == 0);
|
||||
$(XV) = ( ((register & ~operand & ~result) | (~register & operand & result)) & 0x8000 ) != 0;
|
||||
$(XC) = ( ((~register & operand) | (operand & result) | (~register & result)) & 0x8000 ) != 0;
|
||||
}
|
||||
|
||||
macro subtraction_flagsB(register, operand, result) {
|
||||
$(XN) = (result s< 0);
|
||||
$(XZ) = (result == 0);
|
||||
$(XV) = ( ((register & ~operand & ~result) | (~register & operand & result)) & 0x80 ) != 0;
|
||||
$(XC) = ( ((~register & operand) | (operand & result) | (result & ~register)) & 0x80 ) != 0;
|
||||
}
|
||||
|
||||
macro subtraction_flagsC(register, operand, result) {
|
||||
$(XN) = (result s< 0);
|
||||
$(XZ) = ( (result == 0) & ($(XZ) == 1));
|
||||
$(XV) = ( ((register & ~operand & ~result) | (~register & operand & result)) & 0x8000 ) != 0;
|
||||
$(XC) = ( ((~register & operand) | (operand & result) | (~register & result)) & 0x8000 ) != 0;
|
||||
}
|
||||
|
||||
macro shiftFlags(result,old)
|
||||
{
|
||||
$(XN) = (result s< 0);
|
||||
$(XZ) = (result == 0);
|
||||
tmp:2 = (old >> 15) ^ (result >> 15);
|
||||
$(XV) = tmp(1);
|
||||
}
|
||||
|
||||
macro getbit(res,in,bitnum) {
|
||||
res = ((in >> bitnum) & 1) != 0;
|
||||
}
|
||||
|
||||
################################################################
|
||||
# Constructors
|
||||
################################################################
|
||||
|
||||
#rel9 defined in HCS_HC12.sinc
|
||||
# range -256 through +255
|
||||
with : XGATE=1 {
|
||||
rel9: reloc is immrel8 [ reloc = XG_BASE + inst_next + (immrel8 * 2); ] { export * reloc; }
|
||||
|
||||
# range -512 through +512
|
||||
rel10: reloc is immrel9 [ reloc = XG_BASE + inst_next + (immrel9 * 2); ] { export * reloc; }
|
||||
|
||||
rd : reg8 is reg8 { export reg8; }
|
||||
|
||||
rs1: reg5 is reg5 & reg5=0 { export 0:2; }
|
||||
rs1: reg5 is reg5 { export reg5; }
|
||||
|
||||
rs2: reg2 is reg2 & reg2=0 { export 0:2; }
|
||||
rs2: reg2 is reg2 { export reg2; }
|
||||
|
||||
|
||||
# Add with carry
|
||||
:ADC rd, rs1, rs2 is opcode=0x3 & rd & rs1 & rs2 & op2=0x3
|
||||
{
|
||||
local result:2 = rs1 + rs2 + zext($(XC));
|
||||
rd = result;
|
||||
|
||||
addition_flags(rs1, rs2, result);
|
||||
}
|
||||
|
||||
# Add without carry
|
||||
:ADD rd, rs1, rs2 is opcode=0x3 & rd & rs1 & rs2 & op2=0x2
|
||||
{
|
||||
local result:2 = rs1 + rs2;
|
||||
rd = result;
|
||||
|
||||
addition_flags(rs1, rs2, result);
|
||||
}
|
||||
|
||||
# Add immediate 8-bit constant (high byte)
|
||||
:ADDH rd, ximm8 is opcode=0x1d & rd & ximm8
|
||||
{
|
||||
local val:2 = ximm8 << 8;
|
||||
local result:2 = rd + val;
|
||||
|
||||
addition_flags(rd, val, result);
|
||||
|
||||
rd = result;
|
||||
}
|
||||
|
||||
# Add immediate 8-bit constant (low byte)
|
||||
:ADDL rd, ximm8 is opcode=0x1c & rd & ximm8
|
||||
{
|
||||
local result:2 = rd + ximm8;
|
||||
|
||||
$(XN) = (result s< 0);
|
||||
$(XZ) = ((result == 0) & ($(XZ)==1));
|
||||
$(XV) = ((~rd & result) & 0x8000) != 0;
|
||||
$(XC) = ((rd & ~result) & 0x8000) != 0;
|
||||
rd = result;
|
||||
}
|
||||
|
||||
# Logical AND
|
||||
:AND rd, rs1, rs2 is opcode=0x2 & rd & rs1 & rs2 & op2=0x0
|
||||
{
|
||||
local result:2 = rs1 & rs2;
|
||||
rd = result;
|
||||
|
||||
default_flags(result);
|
||||
}
|
||||
|
||||
# Logical AND immediate 8-bit constant (high byte)
|
||||
:ANDH rd, ximm8 is opcode=0x11 & rd & ximm8
|
||||
{
|
||||
local result:2 = (ximm8 << 8) | 0xff;
|
||||
result = rd & result;
|
||||
rd = result;
|
||||
|
||||
default_flagsH(result);
|
||||
}
|
||||
|
||||
# Logical AND immediate 8-bit constant (low byte)
|
||||
:ANDL rd, ximm8 is opcode=0x10 & rd & ximm8
|
||||
{
|
||||
local result:2 = 0xff00 | ximm8;
|
||||
result = rd & result;
|
||||
rd = result;
|
||||
|
||||
default_flagsL(result);
|
||||
}
|
||||
|
||||
# Arithmetic Shift Right
|
||||
:ASR rd, ximm4 is opcode=0x1 & rd & ximm4 & op3=0x9
|
||||
{
|
||||
getbit($(XC), rd, ximm4-1);
|
||||
rd = rd s>> ximm4;
|
||||
|
||||
default_flags(rd);
|
||||
}
|
||||
|
||||
:ASR rd, rs1 is opcode=0x1 & rd & rs1 & op4=0x11
|
||||
{
|
||||
getbit($(XC), rd, rs1-1);
|
||||
rd = rd s>> rs1;
|
||||
|
||||
default_flags(rd);
|
||||
}
|
||||
|
||||
# Branch if Carry Cleared
|
||||
:BCC rel9 is opcode=0x4 & op9_10=0x0 & rel9
|
||||
{
|
||||
if ($(XC) == 0) goto rel9;
|
||||
}
|
||||
|
||||
|
||||
# Branch if Carry Set
|
||||
:BCS rel9 is opcode=0x4 & op9_10=0x1 & rel9
|
||||
{
|
||||
if ($(XC) == 1) goto rel9;
|
||||
}
|
||||
|
||||
# Branch of Equal
|
||||
:BEQ rel9 is opcode=0x4 & op9_10=0x3 & rel9
|
||||
{
|
||||
if ($(XZ) == 1) goto rel9;
|
||||
}
|
||||
|
||||
# Bit Field Extract
|
||||
:BFEXT rd, rs1, rs2 is opcode=0xc & rd & rs1 & rs2 & op2=0x3
|
||||
{
|
||||
local origin:2 = rs2 & 0xf;
|
||||
local width:2 = (rs2 >> 4) & 0xf;
|
||||
local mask:2 = (0xffff >> (16-(width + 1))) << origin;
|
||||
local result:2 = (rs1 & mask) >> origin;
|
||||
|
||||
rd = result;
|
||||
|
||||
default_flags(rd);
|
||||
}
|
||||
|
||||
# Bit Field Find First One
|
||||
:BFFO rd, rs1 is opcode=0x1 & rd & rs1 & op4=0x10
|
||||
{
|
||||
# 15 - count leading zeros
|
||||
tmp:2 = rs1;
|
||||
$(XC) = (rd == 0);
|
||||
#TODO: implement findFirstOne behavior
|
||||
rd = findFirstOne(tmp);
|
||||
|
||||
default_flags(rd);
|
||||
}
|
||||
|
||||
# Bit Field Insert
|
||||
:BFINS rd, rs1, rs2 is opcode=0xd & rd & rs1 & rs2 & op2=0x3
|
||||
{
|
||||
local origin:2 = rs2 & 0xf;
|
||||
local width:2 = (rs2 >> 4) & 0xf;
|
||||
local mask:2 = (0xffff >> (16-(width + 1))) << origin;
|
||||
local result:2 = (rs1 & mask);
|
||||
|
||||
rd = (rd & ~mask) | result;
|
||||
|
||||
default_flags(rd);
|
||||
}
|
||||
|
||||
# Bit Field Insert and Invert
|
||||
:BFINSI rd, rs1, rs2 is opcode=0xe & rd & rs1 & rs2 & op2=0x3
|
||||
{
|
||||
local origin:2 = rs2 & 0xf;
|
||||
local width:2 = (rs2 >> 4) & 0xf;
|
||||
local mask:2 = (0xffff >> (16-(width + 1))) << origin;
|
||||
local result:2 = (~rs1 & mask);
|
||||
|
||||
rd = (rd & ~mask) | result;
|
||||
|
||||
default_flags(rd);
|
||||
}
|
||||
|
||||
# Bit Field Insert and XNOR
|
||||
:BFINSX rd, rs1, rs2 is opcode=0xf & rd & rs1 & rs2 & op2=0x3
|
||||
{
|
||||
local origin:2 = rs2 & 0xf;
|
||||
local width:2 = (rs2 >> 4) & 0xf;
|
||||
local mask:2 = (0xffff >> (16-(width + 1))) << origin;
|
||||
local result:2 = (~(rs1 ^ rd) & mask);
|
||||
|
||||
rd = (rd & ~mask) | result;
|
||||
|
||||
default_flags(rd);
|
||||
}
|
||||
|
||||
# Branch if Greater than or Equal to Zero
|
||||
:BGE rel9 is opcode=0x6 & op9_10=0x2 & rel9
|
||||
{
|
||||
if (($(XN) ^ $(XV)) == 0) goto rel9;
|
||||
}
|
||||
|
||||
# Branch if Greater than Zero
|
||||
:BGT rel9 is opcode=0x7 & op9_10=0x0 & rel9
|
||||
{
|
||||
if (($(XZ) | ($(XN) ^ $(XV))) == 0) goto rel9;
|
||||
}
|
||||
|
||||
# Branch if Higher
|
||||
:BHI rel9 is opcode=0x6 & op9_10=0x0 & rel9
|
||||
{
|
||||
if (($(XC) | $(XZ)) == 0) goto rel9;
|
||||
}
|
||||
|
||||
#:BHS rel9 is opcode=0x4 & op9_10=0x0 & rel9 see BCC
|
||||
|
||||
# Bit Test immediate 8-bit constant (high byte)
|
||||
:BITH rd, ximm8 is opcode=0x13 & rd & ximm8
|
||||
{
|
||||
local val:2 = rd >> 8;
|
||||
val = val & ximm8;
|
||||
|
||||
default_flags(val);
|
||||
}
|
||||
|
||||
# Bit Test immediate 8-bit constant (low byte)
|
||||
:BITL reg8, ximm8 is opcode=0x12 & reg8 & ximm8
|
||||
{
|
||||
local val:2 = reg8 & 0xff;
|
||||
val = val & ximm8;
|
||||
|
||||
default_flags(val);
|
||||
}
|
||||
|
||||
# Branch if Less or Equal to Zero
|
||||
:BLE rel9 is opcode=0x7 & op9_10=0x1 & rel9
|
||||
{
|
||||
if ($(XZ) | ($(XN) ^ $(XV))) goto rel9;
|
||||
}
|
||||
|
||||
#:BLO rel9 is opcode=0x4 & op9_10=0x1 & rel9 See BCS
|
||||
|
||||
# Branch if Lower or Same
|
||||
:BLS rel9 is opcode=0x6 & op9_10=0x1 & rel9
|
||||
{
|
||||
if (($(XC) | $(XZ)) == 1) goto rel9;
|
||||
}
|
||||
|
||||
# Branch of Lower than Zero
|
||||
:BLT rel9 is opcode=0x6 & op9_10=0x3 & rel9
|
||||
{
|
||||
if (($(XN) ^ $(XV)) == 1) goto rel9;
|
||||
}
|
||||
|
||||
# Branch if Minus
|
||||
:BMI rel9 is opcode=0x5 & op9_10=0x1 & rel9
|
||||
{
|
||||
if ($(XN) == 1) goto rel9;
|
||||
}
|
||||
|
||||
# Branch if Not Equal
|
||||
:BNE rel9 is opcode=0x4 & op9_10=0x2 & rel9
|
||||
{
|
||||
if ($(XZ) == 0) goto rel9;
|
||||
}
|
||||
|
||||
# Branch if Plus
|
||||
:BPL rel9 is opcode=0x5 & op9_10=0x0 & rel9
|
||||
{
|
||||
if ($(XN) == 0) goto rel9;
|
||||
}
|
||||
|
||||
# Branch Always
|
||||
:BRA rel10 is opcode=0x7 & bit_10=0x1 & rel10
|
||||
{
|
||||
goto rel10;
|
||||
}
|
||||
# Break
|
||||
:BRK is xop16=0x0
|
||||
{
|
||||
# put xgate into debug mode and set breakpoint
|
||||
goto inst_next;
|
||||
}
|
||||
|
||||
# Branch if Overflow Cleared
|
||||
:BVC rel9 is opcode=0x5 & op9_10=0x2 & rel9
|
||||
{
|
||||
if ($(XV) == 0) goto rel9;
|
||||
}
|
||||
|
||||
# Branch if Overflow Set
|
||||
:BVS rel9 is opcode=0x5 & op9_10=0x3 & rel9
|
||||
{
|
||||
if ($(XV) == 2) goto rel9;
|
||||
}
|
||||
|
||||
# Compare
|
||||
# synonym for SUB R0, RS1, RS2
|
||||
:CMP rs1, rs2 is opcode=0x3 & reg8=0x0 & rs1 & rs2 & op2=0x0
|
||||
{
|
||||
tmp:2 = rs1 - rs2;
|
||||
subtraction_flags(rs1, rs2, tmp);
|
||||
}
|
||||
|
||||
# Compare Immediate 8-bit constant (low byte)
|
||||
:CMPL rd, ximm8 is opcode=0x1a & rd & ximm8
|
||||
{
|
||||
local val:1 = rd:1;
|
||||
local tmp:1 = val - ximm8;
|
||||
local xtmp:1 = ximm8;
|
||||
subtraction_flagsB(val, xtmp, tmp);
|
||||
}
|
||||
|
||||
# One's Complement
|
||||
:COM rd, rs2 is opcode=0x2 & rd & reg5=0x0 & rs2 & op2=0x3
|
||||
{
|
||||
local val:2 = ~rs2;
|
||||
rd = val;
|
||||
|
||||
default_flags(rd);
|
||||
}
|
||||
|
||||
:COM rd is opcode=0x2 & rd & reg5=0x0 & rs2 & reg8=reg2 & op2=0x3
|
||||
{
|
||||
local val:2 = ~rs2;
|
||||
rd = val;
|
||||
|
||||
default_flags(rd);
|
||||
}
|
||||
|
||||
# Compare with Carry
|
||||
:CPC rs1, rs2 is opcode=0x3 & reg8=0x0 & rs1 & rs2 & op2=0x1
|
||||
{
|
||||
local tmp:2 = rs1 - rs2 - zext($(XC));
|
||||
subtraction_flags(rs1, rs2, tmp);
|
||||
}
|
||||
|
||||
# Compare Immediate 8-bit constant with carry (high byte)
|
||||
:CPCH rd, ximm8 is opcode=0x1b & rd & ximm8
|
||||
{
|
||||
local val:2 = rd >> 8;
|
||||
local tmp:1 = val(1) - ximm8 - $(XC);
|
||||
local xtmp:1 = ximm8;
|
||||
subtraction_flagsB(val(1), xtmp, tmp);
|
||||
}
|
||||
|
||||
# Clear Semaphore
|
||||
:CSEM rd is opcode=0x0 & rd & xop8=0xf0
|
||||
{
|
||||
# treat as NOP
|
||||
clearSemaphore();
|
||||
}
|
||||
|
||||
:CSEM imm3 is opcode=0x0 & imm3 & xop8=0xf1
|
||||
{
|
||||
clearSemaphore();
|
||||
}
|
||||
|
||||
|
||||
# Logical Shift Left with Carry
|
||||
:CSL rd, ximm4 is opcode=0x1 & rd & ximm4 & op3=0xa
|
||||
{
|
||||
local Ctmp:2 = zext($(XC));
|
||||
local shift:2 = ((ximm4-1)%16+1);
|
||||
local oldRd:2 = rd >> 15;
|
||||
getbit($(XC), rd, 16-shift);
|
||||
leftShiftCarry(rd,Ctmp,shift,rd);
|
||||
shiftFlags(rd,oldRd);
|
||||
}
|
||||
|
||||
:CSL rd, rs1 is opcode=0x1 & rd & rs1 & op4=0x12
|
||||
{
|
||||
local Ctmp:2 = zext($(XC));
|
||||
#if rs1 > 16, then rs1 = 16
|
||||
local rsgt:2 = zext(rs1>16);
|
||||
local rslt:2 = zext(rs1<16);
|
||||
local shift:2 = rs1*rsgt + 16*rslt;
|
||||
local oldRd:2 = rd >> 15;
|
||||
getbit($(XC), rd, 16-shift);
|
||||
leftShiftCarry(rd,Ctmp,shift,rd);
|
||||
shiftFlags(rd,oldRd);
|
||||
}
|
||||
|
||||
# Logical Shift Right with Carry
|
||||
:CSR rd, ximm4 is opcode=0x1 & rd & ximm4 & op3=0xb
|
||||
{
|
||||
local Ctmp:2 = zext($(XC));
|
||||
local shift:2 = ((ximm4-1)%16+1);
|
||||
local oldRd:2 = rd >> 15;
|
||||
getbit($(XC), rd, shift-1);
|
||||
rightShiftCarry(rd,Ctmp,shift,rd);
|
||||
shiftFlags(rd,oldRd);
|
||||
}
|
||||
|
||||
:CSR rd, rs1 is opcode=0x1 & rd & rs1 & op4=0x13
|
||||
{
|
||||
local Ctmp:2 = zext($(XC));
|
||||
#if rs1 > 16, then rs1 = 16
|
||||
local rsgt:2 = zext(rs1>16);
|
||||
local rslt:2 = zext(rs1<16);
|
||||
local shift:2 = rs1*rsgt + 16*rslt;
|
||||
local oldRd:2 = rd >> 15;
|
||||
getbit($(XC), rd, shift-1);
|
||||
rightShiftCarry(rd,Ctmp,shift,rd);
|
||||
shiftFlags(rd,oldRd);
|
||||
}
|
||||
|
||||
:CSR rd, rs1 is opcode=0x1 & rd & rs1 & reg5=0 & op4=0x13
|
||||
{
|
||||
$(XN) = (rd s< 0);
|
||||
$(XZ) = (rd == 0);
|
||||
$(XV) = 0;
|
||||
# $(XC) is unaffected
|
||||
}
|
||||
|
||||
# Jump and Link
|
||||
:JAL rd is opcode=0x0 & rd & xop8=0xf6
|
||||
{
|
||||
local dest:2 = rd;
|
||||
rd = XPC;
|
||||
call [dest];
|
||||
}
|
||||
|
||||
# Load byte from memory (low byte)
|
||||
:LDB rd, (rs1, offs5) is opcode=0x8 & rd & rs1 & offs5
|
||||
{
|
||||
dst:3 = XG_BASE + zext(rs1) + offs5;
|
||||
local val:1 = *:1 (dst);
|
||||
rd = (rd & 0xff00) | zext(val);
|
||||
}
|
||||
|
||||
:LDB rd, (rs1, rs2) is opcode=0xc & rd & rs1 & rs2 & op2=0x0
|
||||
{
|
||||
dst:3 = XG_BASE + zext(rs1) + zext(rs2);
|
||||
local val:1 = *:1 (dst);
|
||||
rd = (rd & 0xff00) | zext(val);
|
||||
}
|
||||
|
||||
:LDB rd, (rs1, rs2+) is opcode=0xc & rd & rs1 & rs2 & op2=0x1
|
||||
{
|
||||
dst:3 = XG_BASE + zext(rs1) + zext(rs2);
|
||||
local val:1 = *:1 (dst);
|
||||
rd = (rd & 0xff00) | zext(val);
|
||||
rs1 = rs1 + 1;
|
||||
}
|
||||
|
||||
:LDB rd, (rs1, -rs2) is opcode=0xc & rd & rs1 & rs2 & op2=0x2
|
||||
{
|
||||
rs2 = rs2 - 1;
|
||||
dst:3 = XG_BASE + zext(rs1) + zext(rs2);
|
||||
local val:1 = *:1 (dst);
|
||||
rd = (rd & 0xff00) | zext(val);
|
||||
}
|
||||
|
||||
|
||||
# Load Immediate 8-bit constant (high byte)
|
||||
:LDH rd, ximm8 is opcode=0x1f & rd & ximm8
|
||||
{
|
||||
rd = (rd & 0x00ff) | (ximm8 << 8);
|
||||
}
|
||||
|
||||
|
||||
# Load Immediate 8-bit constant (low byte)
|
||||
:LDL rd, ximm8 is opcode=0x1e & rd & ximm8
|
||||
{
|
||||
rd = (rd & 0xff00) | ximm8;
|
||||
}
|
||||
|
||||
# Load Word from Memory
|
||||
:LDW rd, (rs1, offs5) is opcode=0x9 & rd & rs1 & offs5
|
||||
{
|
||||
dst:3 = XG_BASE + zext(rs1) + offs5;
|
||||
local val:2 = *:2 (dst);
|
||||
rd = val;
|
||||
}
|
||||
|
||||
:LDW rd, (rs1, rs2) is opcode=0xd & rd & rs1 & rs2 & op2=0x0
|
||||
{
|
||||
dst:3 = XG_BASE + zext(rs1) + zext(rs2);
|
||||
local val:2 = *:2 (dst);
|
||||
rd = val;
|
||||
}
|
||||
|
||||
:LDW rd, (rs1, rs2+) is opcode=0xd & rd & rs1 & rs2 & op2=0x1
|
||||
{
|
||||
dst:3 = XG_BASE + zext(rs1) + zext(rs2);
|
||||
local val:2 = *:2 (dst);
|
||||
rd = val;
|
||||
rs1 = rs1 + 2;
|
||||
}
|
||||
:LDW rd, (rs1, -rs2) is opcode=0xd & rd & rs1 & rs2 & op2=0x2
|
||||
{
|
||||
rs2 = rs2 - 2;
|
||||
dst:3 = XG_BASE + zext(rs1) + zext(rs2);
|
||||
local val:2 = *:2 (dst);
|
||||
rd = val;
|
||||
}
|
||||
|
||||
# Logical Shift Left
|
||||
:LSL rd, ximm4 is opcode=0x1 & rd & ximm4 & op3=0xc
|
||||
{
|
||||
local shift:2 = ((ximm4-1)%16+1);
|
||||
getbit($(XC), rd, 16-shift);
|
||||
local oldRd:2 = rd >> 15;
|
||||
rd = rd << shift;
|
||||
shiftFlags(rd,oldRd);
|
||||
}
|
||||
|
||||
:LSL rd, rs1 is opcode=0x1 & rd & rs1 & op4=0x14
|
||||
{
|
||||
getbit($(XC), rd, 16-rs1);
|
||||
local oldRd:2 = rd >> 15;
|
||||
rd = rd << rs1;
|
||||
shiftFlags(rd,oldRd);
|
||||
}
|
||||
|
||||
# Logical Shift Right
|
||||
:LSR rd, ximm4 is opcode=0x1 & rd & ximm4 & op3=0xd
|
||||
{
|
||||
getbit($(XC), rd, ximm4-1);
|
||||
local oldRd:2 = rd >> 15;
|
||||
rd = rd << ximm4;
|
||||
shiftFlags(rd,oldRd);
|
||||
}
|
||||
|
||||
:LSR rd, rs1 is opcode=0x1 & rd & rs1 & op4=0x15
|
||||
{
|
||||
getbit($(XC), rd, rs1-1);
|
||||
local oldRd:2 = (rd >> 15);
|
||||
rd = rd << rs1;
|
||||
shiftFlags(rd,oldRd);
|
||||
}
|
||||
|
||||
# Move Register Content
|
||||
# Synonym for OR RD, R0, RS
|
||||
:MOV rd, rs2 is opcode=0x2 & rd & reg5=0 & rs2 & op2=0x2
|
||||
{
|
||||
rd = rs2;
|
||||
|
||||
default_flags(rd);
|
||||
}
|
||||
|
||||
# Two's Complement
|
||||
:NEG rd, rs2 is opcode=0x3 & rd & reg5=0x0 & rs2 & op2=0x0
|
||||
{
|
||||
local tmp:2 = -rs2;
|
||||
rd = tmp;
|
||||
$(XN) = (rd s< 0);
|
||||
$(XZ) = (rd == 0);
|
||||
$(XV) = (((rs2 & rd) & 0x8000) != 0);
|
||||
$(XC) = (((rs2 | rd) & 0x8000) != 0);
|
||||
}
|
||||
|
||||
:NEG rd is opcode=0x3 & rd & reg5=0x0 & rs2 & reg2=reg8 & op2=0x0
|
||||
{
|
||||
local tmp:2 = -rs2;
|
||||
rd = tmp;
|
||||
$(XN) = (rd s< 0);
|
||||
$(XZ) = (rd == 0);
|
||||
$(XV) = (((rs2 & rd) & 0x8000) != 0);
|
||||
$(XC) = (((rs2 | rd) & 0x8000) != 0);
|
||||
}
|
||||
|
||||
# No Op
|
||||
:NOP is xop16=0x100 {}
|
||||
|
||||
# Logical OR
|
||||
:OR rd, rs1, rs2 is opcode=0x2 & rd & rs1 & rs2 & op2=0x2
|
||||
{
|
||||
local result:2 = rs1 | rs2;
|
||||
rd = result;
|
||||
|
||||
default_flags(result);
|
||||
}
|
||||
|
||||
# Logical OR Immediate 8-bit Constant (high byte)
|
||||
:ORH rd, ximm8 is opcode=0x15 & rd & ximm8
|
||||
{
|
||||
local result:2 = (ximm8 << 8);
|
||||
result = rd | result;
|
||||
rd = result;
|
||||
|
||||
default_flagsH(result);
|
||||
}
|
||||
|
||||
# Logical OR Immediate 8-bit Constant (low byte)
|
||||
:ORL rd, ximm8 is opcode=0x14 & rd & ximm8
|
||||
{
|
||||
local result:2 = ximm8;
|
||||
result = rd | result;
|
||||
|
||||
default_flagsL(result);
|
||||
}
|
||||
|
||||
# Calculate Parity
|
||||
:PAR rd is opcode=0x0 & rd & xop8=0xf5
|
||||
{
|
||||
parity(rd, $(XC));
|
||||
|
||||
default_flags(rd);
|
||||
}
|
||||
|
||||
# Rotate Left
|
||||
:ROL rd, ximm4 is opcode=0x1 & rd & ximm4 & op3=0xe
|
||||
{
|
||||
local cnt:2 = ximm4;
|
||||
rd = (rd << cnt) | (rd >> (16 - cnt));
|
||||
|
||||
default_flags(rd);
|
||||
}
|
||||
|
||||
:ROL rd, rs1 is opcode=0x1 & rd & rs1 & op4=0x16
|
||||
{
|
||||
local cnt:2 = rs1 & 0xf;
|
||||
rd = (rd << cnt) | (rd >> (16 - cnt));
|
||||
|
||||
default_flags(rd);
|
||||
}
|
||||
|
||||
# Rotate Right
|
||||
:ROR rd, ximm4 is opcode=0x1 & rd & ximm4 & op3=0xf
|
||||
{
|
||||
local cnt:2 = ximm4;
|
||||
rd = (rd >> cnt) | (rd << (16 - rd));
|
||||
|
||||
default_flags(rd);
|
||||
}
|
||||
|
||||
:ROR rd, rs1 is opcode=0x1 & rd & rs1 & op4=0x17
|
||||
{
|
||||
local cnt:2 = rs1 & 0xf;
|
||||
rd = (rd >> cnt) | (rd << (16 - rd));
|
||||
|
||||
default_flags(rd);
|
||||
}
|
||||
# Return to Scheduler
|
||||
# Implement as NOP for now
|
||||
:RTS is xop16=0x0200 {}
|
||||
|
||||
# Subtract with Carry
|
||||
:SBC rd, rs1, rs2 is opcode=0x3 & rd & rs1 & rs2 & op2=0x1
|
||||
{
|
||||
local result:2 = rs1 - rs2 - zext($(XC));
|
||||
rd = result;
|
||||
subtraction_flagsC(rs1, rs2, result);
|
||||
}
|
||||
|
||||
# Sign Extent Byte to Word
|
||||
:SEX rd is opcode=0x0 & rd & xop8=0xf4
|
||||
{
|
||||
local result:1 = rd:1 & 0xff;
|
||||
rd = sext(result);
|
||||
|
||||
default_flags(rd);
|
||||
}
|
||||
# Set Interrupt Flag
|
||||
# TODO: implement interrupt flags
|
||||
:SIF is xop16=0x0300
|
||||
{
|
||||
setInterruptFlag();
|
||||
}
|
||||
|
||||
:SIF rd is opcode=0x0 & rd & xop8=0xf7
|
||||
{
|
||||
setInterruptFlag();
|
||||
}
|
||||
|
||||
# Set Semaphore
|
||||
# TODO: implement semaphores
|
||||
:SSEM imm3 is opcode=0x0 & imm3 & xop8=0xf2
|
||||
{
|
||||
setSemaphore();
|
||||
}
|
||||
|
||||
:SSEM rd is opcode=0x0 & rd & xop8=0xf3
|
||||
{
|
||||
setSemaphore();
|
||||
}
|
||||
|
||||
# Store Byte to Memory (low byte)
|
||||
:STB rd, (rs1, offs5) is opcode=0xa & rd & rs1 & offs5
|
||||
{
|
||||
dst:3 = XG_BASE + zext(rs1) + offs5;
|
||||
local val:1 = rd:1;
|
||||
*dst = val;
|
||||
}
|
||||
|
||||
:STB rd, (rs1, rs2) is opcode=0xe & rd & rs1 & rs2 & op2=0x0
|
||||
{
|
||||
dst:3 = XG_BASE + zext(rs1) + zext(rs2);
|
||||
local val:1 = rd:1;
|
||||
*dst = val;
|
||||
}
|
||||
|
||||
:STB rd, (rs1, rs2+) is opcode=0xe & rd & rs1 & rs2 & op2=0x1
|
||||
{
|
||||
dst:3 = XG_BASE + zext(rs1) + zext(rs2);
|
||||
local val:1 = rd:1;
|
||||
*dst = val;
|
||||
rs2 = rs2 + 1;
|
||||
}
|
||||
|
||||
:STB rd, (rs1, -rs2) is opcode=0xe & rd & rs1 & rs2 & op2=0x2
|
||||
{
|
||||
rs2 = rs2 - 1;
|
||||
dst:3 = XG_BASE + zext(rs1) + zext(rs2);
|
||||
local val:1 = rd:1;
|
||||
*dst = val;
|
||||
}
|
||||
|
||||
# Store Word to Memory
|
||||
:STW rd, (rs1, offs5) is opcode=0xb & rd & rs1 & offs5
|
||||
{
|
||||
dst:3 = XG_BASE + zext(rs1) + offs5;
|
||||
local val:2 = rd;
|
||||
*dst = val;
|
||||
}
|
||||
|
||||
:STW rd, (rs1, rs2) is opcode=0xf & rd & rs1 & rs2 & op2=0x0
|
||||
{
|
||||
dst:3 = XG_BASE + zext(rs1) + zext(rs2);
|
||||
local val:2 = rd;
|
||||
*dst = val;
|
||||
rs2 = rs2 + 1;
|
||||
}
|
||||
|
||||
:STW rd, (rs1, rs2+) is opcode=0xf & rd & rs1 & rs2 & op2=0x1
|
||||
{
|
||||
dst:3 = XG_BASE + zext(rs1) + zext(rs2);
|
||||
local val:2 = rd;
|
||||
*dst = val;
|
||||
rs2 = rs2 + 2;
|
||||
}
|
||||
|
||||
:STW rd, (rs1, -rs2) is opcode=0xf & rd & rs1 & rs2 & op2=0x2
|
||||
{
|
||||
rs2 = rs2 - 2;
|
||||
dst:3 = XG_BASE + zext(rs1) + zext(rs2);
|
||||
local val:2 = rd;
|
||||
*dst = val;
|
||||
}
|
||||
|
||||
# Subtract without Carry
|
||||
:SUB rd, rs1, rs2 is opcode=0x3 & rd & rs1 & rs2 & op2=0x0
|
||||
{
|
||||
local result:2 = rs1 - rs2;
|
||||
rd = result;
|
||||
|
||||
subtraction_flags(rs1, rs2, result);
|
||||
}
|
||||
|
||||
|
||||
# Subtract Immediate 8-bit constant (high byte)
|
||||
:SUBH rd, ximm8 is opcode=0x19 & rd & ximm8
|
||||
{
|
||||
local val:2 = ximm8 << 8;
|
||||
local result:2 = rd - val;
|
||||
|
||||
subtraction_flags(rd, val, result);
|
||||
|
||||
rd = result;
|
||||
}
|
||||
|
||||
# Subtract Immediate 8-bit constant (low byte)
|
||||
:SUBL rd, ximm8 is opcode=0x18 & rd & ximm8
|
||||
{
|
||||
local val:2 = ximm8;
|
||||
local result:2 = rd - val;
|
||||
|
||||
$(XN) = (result s< 0);
|
||||
$(XZ) = ((result == 0) & ($(XZ)==1));
|
||||
$(XV) = ((~rd & result) & 0x8000) != 0;
|
||||
$(XC) = ((rd & ~result) & 0x8000) != 0;
|
||||
rd = result;
|
||||
}
|
||||
|
||||
# Transfer from and to Special Registers
|
||||
:TFR rd, XCCR is opcode=0x0 & rd & xop8=0xf8 & XCCR
|
||||
{
|
||||
local val:1 = ((($(XN) << 1) | $(XZ) << 1) | $(XV) << 1) | $(XC);
|
||||
rd = zext(val);
|
||||
}
|
||||
|
||||
:TFR XCCR, rd is opcode=0x0 & rd & xop8=0xf9 & XCCR
|
||||
{
|
||||
XCCR = rd & 0xf;
|
||||
$(XN) = rd[3,1];
|
||||
$(XZ) = rd[2,1];
|
||||
$(XV) = rd[1,1];
|
||||
$(XC) = rd[0,1];
|
||||
}
|
||||
|
||||
:TFR rd, XPC is opcode=0x0 & rd & xop8=0xfa & XPC
|
||||
{
|
||||
rd = XPC + 2;
|
||||
}
|
||||
|
||||
# Test Register
|
||||
# Synonym for SUB R0, RS, R0
|
||||
:TST rs1 is opcode=0x3 & reg8=0x0 & rs1 & reg2=0x0 & op2=0x0
|
||||
{
|
||||
local result:2 = rs1;
|
||||
|
||||
subtraction_flags(rs1,0,result);
|
||||
}
|
||||
|
||||
# Logical Exclusive NOR
|
||||
:XNOR rd, rs1, rs2 is opcode=0x2 & rd & rs1 & rs2 & op2=0x3
|
||||
{
|
||||
local result:2 = ~(rs1 ^ rs2);
|
||||
rd = result;
|
||||
|
||||
default_flags(result);
|
||||
}
|
||||
|
||||
# Logical Exclusive NOR Immediate 8-bit constant (high byte)
|
||||
:XNORH rd, ximm8 is opcode=0x17 & rd & ximm8
|
||||
{
|
||||
local result:2 = ximm8 << 0xff;
|
||||
rd = ~(rd ^ result);
|
||||
|
||||
default_flagsH(result);
|
||||
}
|
||||
|
||||
# Logical Exclusive NOR Immediate 8-bit constant (low byte)
|
||||
:XNORL rd, ximm8 is opcode=0x16 & rd & ximm8
|
||||
{
|
||||
local result:2 = ximm8 | 0xff00;
|
||||
rd = ~(rd ^ result);
|
||||
|
||||
default_flagsL(result);
|
||||
}
|
||||
|
||||
}
|
356
Ghidra/Processors/HCS12/data/manuals/HCS12.idx
Normal file
356
Ghidra/Processors/HCS12/data/manuals/HCS12.idx
Normal file
@ -0,0 +1,356 @@
|
||||
@S12XCPUV2.pdf[ CPU12/CPU12X Reference Manual, Rev. v01.04 21 Apr. 2016, nxp.com ]
|
||||
ABA, 84
|
||||
ABX, 85
|
||||
ABY, 86
|
||||
ADCA, 87
|
||||
ADCB, 88
|
||||
ADDA, 89
|
||||
ADDB, 90
|
||||
ADDD, 91
|
||||
ADDX, 92
|
||||
ADDY, 93
|
||||
ADED, 94
|
||||
ADEX, 95
|
||||
ADEY, 96
|
||||
ANDA, 97
|
||||
ANDB, 98
|
||||
ANDCC, 99
|
||||
ANDX, 100
|
||||
ANDY, 101
|
||||
ASL, 102
|
||||
ASLA, 103
|
||||
ASLB, 104
|
||||
ASLD, 105
|
||||
ASLW, 106
|
||||
ASLX, 107
|
||||
ASLY, 108
|
||||
ASR, 109
|
||||
ASRA, 110
|
||||
ASRB, 111
|
||||
ASRW, 112
|
||||
ASRX, 113
|
||||
ASRY, 114
|
||||
BCC, 115
|
||||
BCLR, 116
|
||||
BCS, 117
|
||||
BEQ, 118
|
||||
BGE, 119
|
||||
BGND, 120
|
||||
BGT, 121
|
||||
BHI, 122
|
||||
BHS, 123
|
||||
BITA, 124
|
||||
BITB, 125
|
||||
BITX, 126
|
||||
BITY, 127
|
||||
BLE, 128
|
||||
BLO, 129
|
||||
BLS, 130
|
||||
BLT, 131
|
||||
BMI, 132
|
||||
BNE, 133
|
||||
BPL, 134
|
||||
BRA, 135
|
||||
BRCLR, 136
|
||||
BRN, 137
|
||||
BRSET, 138
|
||||
BSET, 139
|
||||
BSR, 140
|
||||
BTAS, 141
|
||||
BVC, 142
|
||||
BVS, 143
|
||||
CALL, 144
|
||||
CBA, 145
|
||||
CLC, 146
|
||||
CLI, 147
|
||||
CLR, 148
|
||||
CLRA, 149
|
||||
CLRB, 150
|
||||
CLRW, 151
|
||||
CLRX, 152
|
||||
CLRY, 153
|
||||
CLV, 154
|
||||
CMPA, 155
|
||||
CMPB, 156
|
||||
COM, 157
|
||||
COMA, 158
|
||||
COMB, 159
|
||||
COMW, 160
|
||||
COMX, 161
|
||||
COMY, 162
|
||||
CPD, 163
|
||||
CPED, 164
|
||||
CPES, 165
|
||||
CPEX, 166
|
||||
CPEY, 167
|
||||
CPS, 168
|
||||
CPX, 169
|
||||
CPY, 170
|
||||
DAA, 171
|
||||
DBEQ, 172
|
||||
DBNE, 173
|
||||
DEC, 174
|
||||
DECA, 175
|
||||
DECB, 176
|
||||
DECW, 177
|
||||
DECX, 178
|
||||
DECY, 179
|
||||
DES, 180
|
||||
DEX, 181
|
||||
DEY, 182
|
||||
EDIV, 183
|
||||
EDIVS, 184
|
||||
EMACS, 185
|
||||
EMAXD, 186
|
||||
EMAXM, 187
|
||||
EMIND, 188
|
||||
EMINM, 189
|
||||
EMUL, 190
|
||||
EMULS, 191
|
||||
EORA, 192
|
||||
EORB, 193
|
||||
EORX, 194
|
||||
EORY, 195
|
||||
ETBL, 196
|
||||
EXG, 197
|
||||
FDIV, 199
|
||||
GLDAA, 200
|
||||
GLDAB, 201
|
||||
GLDD, 202
|
||||
GLDS, 203
|
||||
GLDX, 204
|
||||
GLDY, 205
|
||||
GSTAA, 206
|
||||
GSTAB, 207
|
||||
GSTD, 208
|
||||
GSTS, 209
|
||||
GSTX, 210
|
||||
GSTY, 211
|
||||
IBEQ, 212
|
||||
IBNE, 213
|
||||
IDIV, 214
|
||||
IDIVS, 215
|
||||
INC, 216
|
||||
INCA, 217
|
||||
INCB, 218
|
||||
INCW, 219
|
||||
INCX, 220
|
||||
INCY, 221
|
||||
INS, 222
|
||||
INX, 223
|
||||
INY, 224
|
||||
JMP, 225
|
||||
JSR, 226
|
||||
LBCC, 227
|
||||
LBCS, 228
|
||||
LBEQ, 229
|
||||
LBGE, 230
|
||||
LBGT, 231
|
||||
LBHI, 232
|
||||
LBHS, 233
|
||||
LBLE, 234
|
||||
LBLO, 235
|
||||
LBLS, 236
|
||||
LBLT, 237
|
||||
LBMI, 238
|
||||
LBNE, 239
|
||||
LBPL, 240
|
||||
LBRA, 241
|
||||
LBRN, 242
|
||||
LBVC, 243
|
||||
LBVS, 244
|
||||
LDAA, 245
|
||||
LDAB, 246
|
||||
LDD, 247
|
||||
LDS, 248
|
||||
LDX, 249
|
||||
LDY, 250
|
||||
LEAS, 251
|
||||
LEAX, 252
|
||||
LEAY, 253
|
||||
LSL, 254
|
||||
LSLA, 255
|
||||
LSLB, 256
|
||||
LSLD, 257
|
||||
LSLW, 258
|
||||
LSLX, 259
|
||||
LSLY, 260
|
||||
LSR, 261
|
||||
LSRA, 262
|
||||
LSRB, 263
|
||||
LSRD, 264
|
||||
LSRW, 265
|
||||
LSRX, 266
|
||||
LSRY, 267
|
||||
MAXA, 268
|
||||
MAXM, 269
|
||||
MEM, 270
|
||||
MINA, 271
|
||||
MINM, 272
|
||||
MOVB, 273
|
||||
MOVW, 280
|
||||
MUL, 287
|
||||
NEG, 288
|
||||
NEGA, 289
|
||||
NEGB, 290
|
||||
NEGW, 291
|
||||
NEGX, 292
|
||||
NEGY, 293
|
||||
NOP, 294
|
||||
ORAA, 295
|
||||
ORAB, 296
|
||||
ORCC, 297
|
||||
ORX, 298
|
||||
ORY, 299
|
||||
PSHA, 300
|
||||
PSHB, 301
|
||||
PSHC, 302
|
||||
PSHCW, 303
|
||||
PSHD, 304
|
||||
PSHX, 305
|
||||
PSHY, 306
|
||||
PULA, 307
|
||||
PULB, 308
|
||||
PULC, 309
|
||||
PULCW, 310
|
||||
PULD, 311
|
||||
PULX, 312
|
||||
PULY, 313
|
||||
REV, 314
|
||||
REVW, 316
|
||||
ROL, 318
|
||||
ROLA, 319
|
||||
ROLB, 320
|
||||
ROLW, 321
|
||||
ROLX, 322
|
||||
ROLY, 323
|
||||
ROR, 324
|
||||
RORA, 325
|
||||
RORB, 326
|
||||
RORW, 327
|
||||
RORX, 328
|
||||
RORY, 329
|
||||
RTC, 330
|
||||
RTI, 331
|
||||
RTS, 332
|
||||
SBA, 333
|
||||
SBCA, 334
|
||||
SBCB, 335
|
||||
SBED, 336
|
||||
SBEX, 337
|
||||
SBEY, 338
|
||||
SEC, 339
|
||||
SEI, 340
|
||||
SEV, 341
|
||||
SEX, 342
|
||||
STAA, 343
|
||||
STAB, 344
|
||||
STD, 345
|
||||
STOP, 346
|
||||
STS, 348
|
||||
STX, 349
|
||||
STY, 350
|
||||
SUBA, 351
|
||||
SUBB, 352
|
||||
SUBD, 353
|
||||
SUBX, 354
|
||||
SUBY, 355
|
||||
SWI, 356
|
||||
SYS, 357
|
||||
TAB, 358
|
||||
TAP, 359
|
||||
TBA, 360
|
||||
TBEQ, 361
|
||||
TBL, 362
|
||||
TBNE, 363
|
||||
TFR, 364
|
||||
TPA, 366
|
||||
TRAP, 367
|
||||
TST, 368
|
||||
TSTA, 369
|
||||
TSTB, 370
|
||||
TSTW, 371
|
||||
TSTX, 372
|
||||
TSTY, 373
|
||||
TSX, 374
|
||||
TSY, 375
|
||||
TXS, 376
|
||||
TYS, 377
|
||||
WAI, 378
|
||||
WAV, 379
|
||||
XGDX, 380
|
||||
XGDY, 381
|
||||
|
||||
@MC9S12XEP100RMV1.pdf[ MC9S12XEP100 Reference Manual, Rev. 1.25 02/2013, nxp.com ]
|
||||
ADC, 389
|
||||
ADD, 390
|
||||
ADDH, 391
|
||||
ADDL, 392
|
||||
AND, 393
|
||||
ANDH, 394
|
||||
ANDL, 395
|
||||
ASR, 396
|
||||
BCC, 397
|
||||
BCS, 398
|
||||
BEQ, 399
|
||||
BFEXT, 400
|
||||
BFFO, 401
|
||||
BFINS, 402
|
||||
BFINSI, 403
|
||||
BFINSX, 404
|
||||
BGE, 405
|
||||
BGT, 406
|
||||
BHI, 407
|
||||
BHS, 408
|
||||
BITH, 409
|
||||
BITL, 410
|
||||
BLE, 411
|
||||
BLO, 412
|
||||
BLS, 413
|
||||
BLT, 414
|
||||
BMI, 415
|
||||
BNE, 416
|
||||
BPL, 417
|
||||
BRA, 418
|
||||
BRK, 419
|
||||
BVC, 420
|
||||
BVS, 421
|
||||
CMP, 422
|
||||
CMPL, 423
|
||||
COM, 424
|
||||
CPC, 425
|
||||
CPCH, 426
|
||||
CSEM, 427
|
||||
CSL, 428
|
||||
CSR, 429
|
||||
JAL, 430
|
||||
LDB, 431
|
||||
LDH, 432
|
||||
LDL, 433
|
||||
LDW, 434
|
||||
LSL, 435
|
||||
LSR, 436
|
||||
MOV, 437
|
||||
NEG, 438
|
||||
NOP, 439
|
||||
OR, 440
|
||||
ORH, 441
|
||||
ORL, 442
|
||||
PAR, 443
|
||||
ROL, 444
|
||||
ROR, 445
|
||||
RTS, 446
|
||||
SBC, 447
|
||||
SEX, 448
|
||||
SIF, 449
|
||||
SSEM, 450
|
||||
STB, 451
|
||||
STW, 452
|
||||
SUB, 453
|
||||
SUBH, 454
|
||||
SUBL, 455
|
||||
TFR, 456
|
||||
TST, 457
|
||||
XNOR, 458
|
||||
XNORH, 459
|
||||
XNORL, 460
|
Loading…
Reference in New Issue
Block a user