Attempt at Python packaging

This commit is contained in:
Duncan Ogilvie
2023-08-12 23:07:54 +02:00
parent 621572f426
commit 828096ce6e
598 changed files with 255445 additions and 141 deletions
+1
View File
@@ -0,0 +1 @@
python/Ghidra/** linguist-generated
+104 -91
View File
@@ -1,111 +1,124 @@
# This file is autogenerated by maturin v1.0.1
# To update, run
#
# maturin generate-ci github
#
name: CI name: CI
on: on: [push, pull_request]
push:
branches:
- main
- master
tags:
- '*'
pull_request:
workflow_dispatch:
permissions:
contents: read
jobs: jobs:
linux: # linux:
runs-on: ubuntu-latest # runs-on: ubuntu-latest
strategy: # strategy:
matrix: # matrix:
target: [x86_64, aarch64] # target: [x86_64, aarch64]
steps: # steps:
- uses: actions/checkout@v3 # - uses: actions/checkout@v3
with: # with:
submodules: 'true' # submodules: 'true'
- uses: actions/setup-python@v4
with: # - uses: actions/setup-python@v4
python-version: '3.10' # with:
- name: Build wheels # python-version: '3.10'
uses: PyO3/maturin-action@v1
with: # - name: Install Rust toolchain
target: ${{ matrix.target }} # uses: dtolnay/rust-toolchain@stable
args: --release --out dist --find-interpreter # with:
sccache: 'true' # targets: aarch64-linux-gnu, x86-64-linux-gnu
manylinux: auto
- name: Upload wheels
uses: actions/upload-artifact@v3
with:
name: wheels
path: dist
windows: # - name: Install Rust aarch64-apple-darwin target
runs-on: windows-latest # if: matrix.platform.os == 'macos-latest'
strategy: # run: rustup target add aarch64-apple-darwin
matrix:
target: [x64] # - name: Upload wheels
steps: # uses: actions/upload-artifact@v3
- uses: actions/checkout@v3 # with:
with: # name: wheels
submodules: 'true' # path: dist
- uses: actions/setup-python@v4
with: # windows:
python-version: '3.10' # runs-on: windows-latest
architecture: ${{ matrix.target }} # strategy:
- name: Build wheels # matrix:
uses: PyO3/maturin-action@v1 # target: [x64]
with: # steps:
target: ${{ matrix.target }} # - uses: actions/checkout@v3
args: --release --out dist --find-interpreter # with:
sccache: 'true' # submodules: 'true'
- name: Upload wheels
uses: actions/upload-artifact@v3 # - uses: actions/setup-python@v4
with: # with:
name: wheels # python-version: '3.10'
path: dist # architecture: ${{ matrix.target }}
# - name: Build wheels
# uses: PyO3/maturin-action@v1
# with:
# target: ${{ matrix.target }}
# args: --release --out dist --find-interpreter
# sccache: 'true'
# - name: Upload wheels
# uses: actions/upload-artifact@v3
# with:
# name: wheels
# path: dist
macos: macos:
# Skip building pull requests from the same repository
if: ${{ github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository) }}
runs-on: macos-latest runs-on: macos-latest
strategy:
matrix:
target: [x86_64, aarch64]
steps: steps:
- uses: actions/checkout@v3 - name: Checkout
uses: actions/checkout@v3
with: with:
submodules: 'true' submodules: 'true'
- uses: actions/setup-python@v4
- name: Python environment
uses: actions/setup-python@v4
with: with:
python-version: '3.10' python-version: '3.10'
- name: Build wheels
uses: PyO3/maturin-action@v1 - name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with: with:
target: ${{ matrix.target }} targets: aarch64-apple-darwin, x86_64-apple-darwin
args: --release --out dist --find-interpreter
sccache: 'true' - name: Build
shell: bash
env:
DEVELOPER_DIR: /Applications/Xcode.app/Contents/Developer
MACOSX_DEPLOYMENT_TARGET: '10.9'
ARCHFLAGS: -arch x86_64 -arch arm64
PYO3_CROSS_LIB_DIR: /Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.8/lib
run: |
pip install -r requirements.txt
python setup.py bdist_wheel --py-limited-api=cp37
pip install --force-reinstall dist/*_universal2.whl
python -c "import icicle"
- name: Test
run: |
pip install -r tests/requirements.txt
python tests/example.py
python tests/invalid.py
- name: Upload wheels - name: Upload wheels
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v3
with: with:
name: wheels name: wheels
path: dist path: dist
release:
name: Release # release:
runs-on: ubuntu-latest # name: Release
if: "startsWith(github.ref, 'refs/tags/')" # runs-on: ubuntu-latest
needs: [linux, windows, macos] # if: "startsWith(github.ref, 'refs/tags/')"
steps: # needs: [linux, windows, macos]
- uses: actions/download-artifact@v3 # steps:
with: # - uses: actions/download-artifact@v3
name: wheels # with:
- name: Publish to PyPI # name: wheels
uses: PyO3/maturin-action@v1 # - name: Publish to PyPI
env: # uses: PyO3/maturin-action@v1
MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }} # env:
with: # MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
command: upload # with:
args: --skip-existing * # command: upload
# args: --skip-existing *
+7 -1
View File
@@ -5,4 +5,10 @@ debug/
venv*/ venv*/
.env/ .env/
dist/ dist/
.DS_Store build/
.DS_Store
__pycache__/
*.egg-info/
*.so
*.dll
*.dylib
Generated
+21 -12
View File
@@ -321,7 +321,7 @@ dependencies = [
"cranelift-module", "cranelift-module",
"cranelift-native", "cranelift-native",
"icicle-cpu", "icicle-cpu",
"memoffset", "memoffset 0.8.0",
"pcode", "pcode",
"target-lexicon", "target-lexicon",
"tracing", "tracing",
@@ -463,6 +463,15 @@ dependencies = [
"autocfg", "autocfg",
] ]
[[package]]
name = "memoffset"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c"
dependencies = [
"autocfg",
]
[[package]] [[package]]
name = "miniz_oxide" name = "miniz_oxide"
version = "0.7.1" version = "0.7.1"
@@ -552,15 +561,15 @@ dependencies = [
[[package]] [[package]]
name = "pyo3" name = "pyo3"
version = "0.18.3" version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3b1ac5b3731ba34fdaa9785f8d74d17448cd18f30cf19e0c7e7b1fdb5272109" checksum = "e681a6cfdc4adcc93b4d3cf993749a4552018ee0a9b65fc0ccfad74352c72a38"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"indexmap", "indexmap",
"indoc", "indoc",
"libc", "libc",
"memoffset", "memoffset 0.9.0",
"parking_lot", "parking_lot",
"pyo3-build-config", "pyo3-build-config",
"pyo3-ffi", "pyo3-ffi",
@@ -570,9 +579,9 @@ dependencies = [
[[package]] [[package]]
name = "pyo3-build-config" name = "pyo3-build-config"
version = "0.18.3" version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9cb946f5ac61bb61a5014924910d936ebd2b23b705f7a4a3c40b05c720b079a3" checksum = "076c73d0bc438f7a4ef6fdd0c3bb4732149136abd952b110ac93e4edb13a6ba5"
dependencies = [ dependencies = [
"once_cell", "once_cell",
"target-lexicon", "target-lexicon",
@@ -580,9 +589,9 @@ dependencies = [
[[package]] [[package]]
name = "pyo3-ffi" name = "pyo3-ffi"
version = "0.18.3" version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd4d7c5337821916ea2a1d21d1092e8443cf34879e53a0ac653fbb98f44ff65c" checksum = "e53cee42e77ebe256066ba8aa77eff722b3bb91f3419177cf4cd0f304d3284d9"
dependencies = [ dependencies = [
"libc", "libc",
"pyo3-build-config", "pyo3-build-config",
@@ -590,9 +599,9 @@ dependencies = [
[[package]] [[package]]
name = "pyo3-macros" name = "pyo3-macros"
version = "0.18.3" version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a9d39c55dab3fc5a4b25bbd1ac10a2da452c4aca13bb450f22818a002e29648d" checksum = "dfeb4c99597e136528c6dd7d5e3de5434d1ceaf487436a3f03b2d56b6fc9efd1"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"pyo3-macros-backend", "pyo3-macros-backend",
@@ -602,9 +611,9 @@ dependencies = [
[[package]] [[package]]
name = "pyo3-macros-backend" name = "pyo3-macros-backend"
version = "0.18.3" version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97daff08a4c48320587b5224cc98d609e3c27b6d437315bd40b605c98eeb5918" checksum = "947dc12175c254889edc0c02e399476c2f652b4b9ebd123aa655c224de259536"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
+2 -2
View File
@@ -15,10 +15,10 @@ icicle-vm = { path = "icicle-emu/icicle-vm" }
pcode = { path = "icicle-emu/sleigh/pcode" } pcode = { path = "icicle-emu/sleigh/pcode" }
sleigh-runtime = { path = "icicle-emu/sleigh/sleigh-runtime" } sleigh-runtime = { path = "icicle-emu/sleigh/sleigh-runtime" }
indexmap = "1.9.3" indexmap = "1.9.3"
pyo3 = { version = "0.18.3", features = ["extension-module", "indexmap"] } pyo3 = { version = "0.19.2", features = ["extension-module", "indexmap", "abi3-py37"] }
target-lexicon = "0.12.7" target-lexicon = "0.12.7"
tracing = "*" tracing = "*"
tracing-subscriber = "0.3.17" tracing-subscriber = "0.3.17"
[build-dependencies] [build-dependencies]
pyo3-build-config = "0.18.3" pyo3-build-config = "0.19.2"
+23
View File
@@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
+12
View File
@@ -0,0 +1,12 @@
include Cargo.lock
include Cargo.toml
include README.md
include build.rs
include requirements.txt
include copy-ghidra.py
recursive-include src *
recursive-include icicle-emu *
recursive-include python *.py
recursive-include python *.pyi
recursive-include python py.typed
recursive-include python/icicle/Ghidra *
+39
View File
@@ -0,0 +1,39 @@
from os import makedirs
from pathlib import Path
from shutil import copytree, rmtree
from argparse import ArgumentParser
def main():
parser = ArgumentParser()
parser.add_argument("ghidra_src", help="Path to the Ghidra source code")
args = parser.parse_args()
ghidra_src = Path(args.ghidra_src)
if not ghidra_src.is_dir():
raise FileNotFoundError(f"Not a directory: {ghidra_src}")
processors = ghidra_src.joinpath("Ghidra", "Processors")
if not ghidra_src.is_dir():
raise FileNotFoundError(f"Not found: {processors}")
target_root = Path.cwd().joinpath("python", "icicle", "Ghidra", "Processors")
if target_root.exists():
rmtree(target_root)
for processor in processors.glob("*"):
if not processor.is_dir():
continue
name = processor.name
languages = processor.joinpath("data", "languages")
if not languages.is_dir():
print(f"Processor skipped: {name}")
continue
print(f"Processor: {name}")
processor_root = target_root.joinpath(name, "data", "languages")
copytree(languages, processor_root, dirs_exist_ok=True)
continue
for file in languages.glob("*"):
if not file.is_file():
print(f"Skip: {file}")
continue
destination = processor_root.joinpath(file.name)
print(f"Copy {file} -> {destination}")
if __name__ == "__main__":
main()
+5 -13
View File
@@ -1,15 +1,7 @@
[build-system] [build-system]
requires = ["maturin>=1.0,<2.0"] requires = [
build-backend = "maturin" "setuptools",
"wheel",
[project] "setuptools-rust",
name = "icicle-emu"
requires-python = ">=3.7"
classifiers = [
"Programming Language :: Rust",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
] ]
build-backend = "setuptools.build_meta"
[tool.maturin]
features = ["pyo3/extension-module"]
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<compiler_spec>
<global>
<range space="RAM"/>
</global>
<stackpointer register="SP" space="RAM" growth="negative"/>
<returnaddress>
<varnode space="stack" offset="1" size="2"/>
</returnaddress>
<default_proto>
<prototype name="__stdcall" extrapop="2" stackshift="2" strategy="register">
<input>
<pentry minsize="1" maxsize="1">
<register name="A"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="X"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="Y"/>
</pentry>
</input>
<output>
<pentry minsize="1" maxsize="1">
<register name="A"/>
</pentry>
</output>
<unaffected>
<register name="SP"/>
</unaffected>
</prototype>
</default_proto>
</compiler_spec>
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<language_definitions>
<language processor="6502"
endian="little"
size="16"
variant="default"
version="1.0"
slafile="6502.sla"
processorspec="6502.pspec"
manualindexfile="../manuals/6502.idx"
id="6502:LE:16:default">
<description>6502 Microcontroller Family</description>
<compiler name="default" spec="6502.cspec" id="default"/>
<external_name tool="IDA-PRO" name="m6502"/>
</language>
<language processor="65C02"
endian="little"
size="16"
variant="default"
version="1.0"
slafile="65c02.sla"
processorspec="6502.pspec"
manualindexfile="../manuals/65c02.idx"
id="65C02:LE:16:default">
<description>65C02 Microcontroller Family</description>
<compiler name="default" spec="6502.cspec" id="default"/>
<external_name tool="IDA-PRO" name="m65c02"/>
</language>
</language_definitions>
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<processor_spec>
<programcounter register="PC"/>
<default_symbols>
<symbol name="NMI" address="FFFA" entry="true" type="code_ptr"/>
<symbol name="RES" address="FFFC" entry="true" type="code_ptr"/>
<symbol name="IRQ" address="FFFE" entry="true" type="code_ptr"/>
</default_symbols>
<default_memory_blocks>
<memory_block name="ZERO_PAGE" start_address="0x0000" length="0x0100" initialized="false"/>
<memory_block name="STACK" start_address="0x0100" length="0x0100" initialized="false"/>
</default_memory_blocks>
</processor_spec>
@@ -0,0 +1,499 @@
# sleigh specification file for MOS 6502
define endian=little;
define alignment=1;
define space RAM type=ram_space size=2 default;
define space register type=register_space size=1;
define register offset=0x00 size=1 [ A X Y P ];
define register offset=0x20 size=2 [ PC SP ];
define register offset=0x20 size=1 [ PCL PCH S SH ];
define register offset=0x30 size=1 [ N V B D I Z C ]; # status bits
#TOKENS
define token opbyte (8)
op = (0,7)
aaa = (5,7)
bbb = (2,4)
cc = (0,1)
;
define token data8 (8)
imm8 = (0,7)
rel = (0,7) signed
;
define token data (16)
imm16 = (0,15)
;
macro popSR() {
SP = SP + 1;
local ccr = *:1 SP;
N = ccr[7,1];
V = ccr[6,1];
B = ccr[4,1];
D = ccr[3,1];
I = ccr[2,1];
Z = ccr[1,1];
C = ccr[0,1];
}
macro pushSR() {
local ccr:1 = 0xff;
ccr[7,1] = N;
ccr[6,1] = V;
ccr[4,1] = B;
ccr[3,1] = D;
ccr[2,1] = I;
ccr[1,1] = Z;
ccr[0,1] = C;
*:1 (SP) = ccr;
SP = SP -1;
}
macro resultFlags(value) {
Z = (value == 0);
N = (value s< 0);
}
macro subtraction_flags1(register, operand, result) {
local complement_register = ~register;
V = ( ((register & ~operand & ~result) | (complement_register & operand & result)) & 0b10000000 ) != 0;
N = (result s< 0);
Z = (result == 0);
C = ( ((complement_register & operand) | (operand & result) | (result & complement_register)) & 0b10000000 ) != 0;
}
################################################################
# Pseudo Instructions
################################################################
define pcodeop readIRQ;
################################################################
REL: reloc is rel [ reloc = inst_next + rel; ] { export *:2 reloc; }
# Immediate
OP1: "#"imm8 is bbb=2; imm8 { tmp:1 = imm8; export tmp; }
# Zero Page
OP1: imm8 is bbb=1; imm8 { export *:1 imm8; }
# Zero Page Indexed X
OP1: imm8,X is bbb=5 & X; imm8 { tmp:2 = zext(imm8 + X); export *:1 tmp; }
# Absolute
OP1: imm16 is bbb=3; imm16 { export *:1 imm16; }
# Absolute Indexed X
OP1: imm16,X is bbb=7 & X; imm16 { tmp:2 = imm16 + zext(X); export *:1 tmp; }
# Absolute Indexed Y
OP1: imm16,Y is bbb=6 & Y; imm16 { tmp:2 = imm16 + zext(Y); export *:1 tmp; }
# Indirect X
OP1: (imm8,X) is bbb=0 & X; imm8 { addr:2 = zext(imm8 + X); tmp:2 = *:2 addr; export *:1 tmp; }
# Indirect Y
OP1: (imm8),Y is bbb=4 & Y; imm8 { addr:2 = imm8; tmp:2 = *:2 addr; tmp = tmp + zext(Y); export *:1 tmp; }
# Immediate
OP2: "#"imm8 is bbb=0; imm8 { tmp:1 = imm8; export tmp; }
# Zero Page
OP2: imm8 is bbb=1; imm8 { export *:1 imm8; }
OP2: A is bbb=2 & A { export A; }
# Absolute
OP2: imm16 is bbb=3; imm16 { export *:1 imm16; }
# Zero Page Indexed X
OP2: imm8,X is bbb=5 & X; imm8 { tmp:2 = zext(imm8 + X); export *:1 tmp; }
# Absolute Indexed X
OP2: imm16,X is bbb=7 & X; imm16 { tmp:2 = imm16 + zext(X); export *:1 tmp; }
OP2ST: OP2 is OP2 { export OP2; }
OP2ST: imm8,Y is bbb=5 & Y; imm8 { tmp:2 = zext(imm8 + Y); export *:1 tmp; }
OP2LD: OP2 is OP2 { export OP2; }
OP2LD: imm8,Y is bbb=5 & Y; imm8 { tmp:2 = zext(imm8 + Y); export *:1 tmp; }
OP2LD: imm16,Y is bbb=7 & Y; imm16 { tmp:2 = imm16 + zext(Y); export *:1 tmp; }
ADDR8: imm8 is imm8 { export *:1 imm8; }
ADDR16: imm16 is imm16 { export *:1 imm16; }
ADDRI: (imm16) is imm16 { tmp:2 = imm16; export *:2 tmp; }
# Instructions
:ADC OP1 is (cc=1 & aaa=3) ... & OP1
{
local op1 = OP1;
local tmpC = C;
C = carry(A, op1);
A = A + op1 + tmpC;
resultFlags(A);
V = C;
}
:AND OP1 is (cc=1 & aaa=1) ... & OP1
{
A = A & OP1;
resultFlags(A);
}
:ASL OP2 is (op=0x06 | op=0x0A | op=0x0E | op=0x16 | op=0x1E) ... & OP2
{
local tmp = OP2;
C = tmp >> 7;
tmp = tmp << 1;
OP2 = tmp;
resultFlags(tmp);
}
:BCC REL is op=0x90; REL
{
if (C == 0) goto REL;
}
:BCS REL is op=0xB0; REL
{
if (C) goto REL;
}
:BEQ REL is op=0xF0; REL
{
if (Z) goto REL;
}
:BIT OP2 is (op=0x24 | op=0x2C) ... & OP2
{
N = (OP2 & 0x80) == 0x80;
V = (OP2 & 0x40) == 0x40;
local value = A & OP2;
Z = (value == 0);
}
:BMI REL is op=0x30; REL
{
if (N) goto REL;
}
:BNE REL is op=0xD0; REL
{
if (Z == 0) goto REL;
}
:BPL REL is op=0x10; REL
{
if (N == 0) goto REL;
}
:BRK is op=0x00
{
*:2 (SP - 1) = inst_next;
SP = SP - 2;
B = 1;
pushSR();
I = 1;
local target:2 = 0xFFFE;
goto [*:2 target];
}
:BVC REL is op=0x50; REL
{
if (V == 0) goto REL;
}
:BVS REL is op=0x70; REL
{
if (V) goto REL;
}
:CLC is op=0x18
{
C = 0;
}
:CLD is op=0xD8
{
D = 0;
}
:CLI is op=0x58
{
I = 0;
}
:CLV is op=0xB8
{
V = 0;
}
:CMP OP1 is (cc=1 & aaa=6) ... & OP1
{
local op1 = OP1;
local tmp = A - op1;
resultFlags(tmp);
C = (A >= op1);
}
:CPX OP2 is (op=0xE0 | op=0xE4 | op=0xEC) ... & OP2
{
local op1 = OP2;
local tmp = X - op1;
resultFlags(tmp);
C = (X >= op1);
}
:CPY OP2 is (op=0xC0 | op=0xC4 | op=0xCC) ... & OP2
{
local op1 = OP2;
local tmp = Y - op1;
resultFlags(tmp);
C = (Y >= op1);
}
:DEC OP2 is (op=0xC6 | op=0xCE | op=0xD6 | op=0xDE) ... & OP2
{
local tmp = OP2 - 1;
OP2 = tmp;
resultFlags(tmp);
}
:DEX is op=0xCA
{
X = X - 1;
resultFlags(X);
}
:DEY is op=0x88
{
Y = Y -1;
resultFlags(Y);
}
:EOR OP1 is (cc=1 & aaa=2) ... & OP1
{
local op1 = OP1;
A = A ^ op1;
resultFlags(A);
}
:INC OP2 is (op=0xE6 | op=0xEE | op=0xF6 | op=0xFE) ... & OP2
{
local tmp = OP2 + 1;
OP2 = tmp;
resultFlags(tmp);
}
:INY is op=0xC8
{
Y = Y + 1;
resultFlags(Y);
}
:INX is op=0xE8
{
X = X + 1;
resultFlags(X);
}
:JMP ADDR16 is (op=0x4C); ADDR16
{
goto ADDR16;
}
:JMP ADDRI is (op=0x6c); ADDRI
{
goto [ADDRI];
}
:JSR ADDR16 is op=0x20; ADDR16
{
*:2 (SP-1) = inst_next;
SP=SP-2;
call ADDR16;
}
:LDA OP1 is (cc=1 & aaa=5) ... & OP1
{
A = OP1;
resultFlags(A);
}
:LDY OP2 is (op=0xA0 | op=0xA4 | op=0xAC | op=0xB4 | op=0xBC) ... & OP2
{
Y = OP2;
resultFlags(Y);
}
:LDX OP2LD is (op=0xA2 | op=0xA6 | op=0xAE | op=0xB6 | op=0xBE) ... & OP2LD
{
X = OP2LD;
resultFlags(X);
}
:LSR OP2 is (op=0x46 | op=0x4A | op=0x4E | op=0x56 | op=0x5E) ... & OP2
{
local tmp = OP2;
C = tmp & 1;
tmp = tmp >> 1;
OP2 = tmp;
Z = (tmp == 0);
N = 0;
}
:NOP is op=0xEA
{
}
:ORA OP1 is (cc=1 & aaa=0) ... & OP1
{
A = A | OP1;
resultFlags(A);
}
:PHP is op=0x8
{
pushSR();
}
:PLP is op=0x28
{
popSR();
}
:PHA is op=0x48
{
*:1 (SP) = A;
SP = SP - 1;
}
:PLA is op=0x68
{
SP = SP + 1;
A = *:1 (SP);
resultFlags(A);
}
:ROL OP2 is (op=0x26 | op=0x2A | op=0x2E | op=0x36 | op=0x3E) ... & OP2
{
local tmpC = C;
local op2 = OP2;
C = op2 >> 7;
local result = op2 << 1;
result = result | tmpC;
OP2 = result;
resultFlags(result);
}
:ROR OP2 is (op=0x66 | op=0x6A | op=0x6E | op=0x76 | op=0x7E) ... & OP2
{
local tmpC = C << 7;
local tmp = OP2;
C = tmp & 1;
tmp = tmp >> 1;
tmp = tmp | tmpC;
OP2 = tmp;
resultFlags(tmp);
}
:RTI is op=0x40
{
popSR();
SP = SP+1;
tmp:2 = *:2 SP;
SP = SP+1;
return [tmp];
}
:RTS is op=0x60
{
SP = SP+1;
tmp:2 = *:2 SP;
SP = SP+1;
return [tmp];
}
:SBC OP1 is (cc=1 & aaa=7) ... & OP1
{
local op1 = OP1;
local result = A - op1 - !C;
subtraction_flags1(A, op1, result);
A = result;
# resultFlags(tmp);
# C = ((A <= op1) * C) | (A < op1);
# A = tmp;
}
:SEC is op=0x38
{
C = 1;
}
:SED is op=0xF8
{
D = 1;
}
:SEI is op=0x78
{
I = 1;
}
:STA OP1 is (cc=1 & aaa=4) ... & OP1
{
OP1 = A;
}
:STX OP2ST is (op=0x86 | op=0x8E | op=0x96) ... & OP2ST
{
OP2ST = X;
}
:STY OP2 is (op=0x84 | op=0x8C | op=0x94) ... & OP2
{
OP2 = Y;
}
:TAX is op=0xAA
{
X = A;
resultFlags(X);
}
:TAY is op=0xA8
{
Y = A;
resultFlags(Y);
}
:TSX is op=0xBA
{
X = S;
}
:TXA is op=0x8A
{
A = X;
resultFlags(A);
}
:TXS is op=0x9A
{
S = X;
}
:TYA is op=0x98
{
A = Y;
resultFlags(A);
}
@@ -0,0 +1,222 @@
@include "6502.slaspec"
define token bitopbyte (8)
bitop = (0,7)
action = (7,7)
bitindex = (4,6) dec
optype = (0,3)
;
define token testopbyte (8)
top = (0, 7)
taaa = (5, 7)
td = (4, 4)
tbb = (2, 3)
tcc = (0, 1)
;
################################################################
# Zero Page Indirect
ZIOP: (imm8) is bbb=4; imm8 { addr:2 = imm8; tmp:2 = *:2 addr; export *:1 tmp; }
OPTB: imm8 is tbb=1; imm8 { export *:1 imm8; }
OPTB: imm16 is tbb=3; imm16 { export *:1 imm16; }
# Absolute Indexed Indirect
ADDRIX: (imm16,X) is X; imm16 { addr:2 = imm16 + zext(X); tmp:2 = *:2 addr; export tmp; }
# Instructions
:ADC ZIOP is (cc=2 & aaa=3) ... & ZIOP
{
local op1 = ZIOP;
local tmpC = C;
C = carry(A, op1);
A = A + op1 + tmpC;
resultFlags(A);
V = C;
}
:AND ZIOP is (cc=2 & aaa=1) ... & ZIOP
{
A = A & ZIOP;
resultFlags(A);
}
:BBR "#"bitindex, imm8, REL is (action=0 & optype=0xF) & bitindex ; imm8 ; REL {
local ptr:2 = imm8;
local value:1 = *:1 ptr;
local jump = (value & (1 << bitindex)) == 0;
if (jump) goto REL;
}
:BBS "#"bitindex, imm8, REL is (action=1 & optype=0xF) & bitindex ; imm8 ; REL {
local ptr:2 = imm8;
local value:1 = *:1 ptr;
local jump = (value & (1 << bitindex)) != 0;
if (jump) goto REL;
}
:BIT "#"imm8 is op=0x89; imm8
{
local value:1 = imm8;
N = (value & 0x80) == 0x80;
V = (value & 0x40) == 0x40;
value = A & value;
Z = (value == 0);
}
:BIT OP2 is (op=0x34 | op=0x3C) ... & OP2
{
N = (OP2 & 0x80) == 0x80;
V = (OP2 & 0x40) == 0x40;
local value = A & OP2;
Z = (value == 0);
}
:BRA REL is op=0x80; REL
{
goto REL;
}
:CMP ZIOP is (cc=2 & aaa=6) ... & ZIOP
{
local op1 = ZIOP;
local tmp = A - op1;
resultFlags(tmp);
C = (A >= op1);
}
:DEC A is op=0x3A & A
{
local tmp = A - 1;
A = tmp;
resultFlags(tmp);
}
:EOR ZIOP is (cc=2 & aaa=2) ... & ZIOP
{
local op1 = ZIOP;
A = A ^ op1;
resultFlags(A);
}
:INC A is op=0x1A & A
{
A = A + 1;
resultFlags(A);
}
:JMP ADDRIX is (op=0x7C); ADDRIX
{
goto [ADDRIX];
}
:LDA ZIOP is (cc=2 & aaa=5) ... & ZIOP
{
A = ZIOP;
resultFlags(A);
}
:ORA ZIOP is (cc=2 & aaa=0) ... & ZIOP
{
A = A | ZIOP;
resultFlags(A);
}
:PHX is op=0xDA
{
*:1 (SP) = X;
SP = SP - 1;
}
:PLX is op=0xFA
{
SP = SP + 1;
X = *:1 (SP);
resultFlags(X);
}
:PHY is op=0x5A
{
*:1 (SP) = Y;
SP = SP - 1;
}
:PLY is op=0x7A
{
SP = SP + 1;
Y = *:1 (SP);
resultFlags(Y);
}
:RMB "#"bitindex, imm8 is (action=0 & optype=7) & bitindex ; imm8 {
local ptr:2 = imm8;
local value:1 = *:1 ptr;
value = value & ~(1 << bitindex);
*:1 ptr = value;
}
:SBC ZIOP is (cc=2 & aaa=7) ... & ZIOP
{
local op1 = ZIOP;
local result = A - op1 - !C;
subtraction_flags1(A, op1, result);
A = result;
}
:SMB "#"bitindex, imm8 is (action=1 & optype=7) & bitindex ; imm8 {
local ptr:2 = imm8;
local value:1 = *:1 ptr;
value = value | (1 << bitindex);
*:1 ptr = value;
}
:STA ZIOP is (cc=2 & aaa=4) ... & ZIOP
{
ZIOP = A;
}
:STZ imm8 is op=0x64 ; imm8
{
local tmp:2 = imm8;
*:1 tmp = 0;
}
:STZ imm8,X is op=0x74 & X ; imm8
{
local tmp:2 = zext(imm8 + X);
*:1 tmp = 0;
}
:STZ imm16 is op=0x9C ; imm16
{
local tmp:2 = imm16;
*:1 tmp = 0;
}
:STZ imm16,X is op=0x9E & X ; imm16
{
local tmp:2 = imm16 + zext(X);
*:1 tmp = 0;
}
:TRB OPTB is (tcc=0 & taaa=0 & td=1) ... & OPTB
{
local op1 = OPTB;
local result = (~A) & op1;
OPTB = result;
Z = result == 0;
}
:TSB OPTB is (tcc=0 & taaa=0 & td=0) ... & OPTB
{
local op1 = OPTB;
local result = A | op1;
OPTB = result;
Z = result == 0;
}
@@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<compiler_spec>
<data_organization>
<absolute_max_alignment value="0" />
<machine_alignment value="8" />
<default_alignment value="1" />
<default_pointer_alignment value="4" />
<pointer_size value="4" />
<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="10" /> <!-- aligned-length=12 -->
<size_alignment_map>
<entry size="1" alignment="1" />
<entry size="2" alignment="2" />
<entry size="4" alignment="4" />
<entry size="8" alignment="4" />
</size_alignment_map>
</data_organization>
<global>
<range space="ram"/>
</global>
<stackpointer register="SP" space="ram"/>
<default_proto>
<prototype name="__stdcall" extrapop="4" stackshift="4" strategy="register">
<input>
<pentry minsize="1" maxsize="4" metatype="ptr">
<register name="A0"/>
</pentry>
<pentry minsize="1" maxsize="4" metatype="ptr">
<register name="A1"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="D0"/>
</pentry>
<pentry minsize="1" maxsize="4">
<register name="D1"/>
</pentry>
<pentry minsize="1" maxsize="500" align="4">
<addr offset="4" space="stack"/>
</pentry>
</input>
<output>
<pentry minsize="1" maxsize="4">
<register name="D0"/>
</pentry>
</output>
<unaffected>
<register name="D2"/>
<register name="D3"/>
<register name="D4"/>
<register name="D5"/>
<register name="D6"/>
<register name="D7"/>
<register name="A2"/>
<register name="A3"/>
<register name="A4"/>
<register name="A5"/>
<register name="A6"/>
<register name="SP"/>
</unaffected>
</prototype>
</default_proto>
</compiler_spec>
@@ -0,0 +1,10 @@
<dwarf>
<register_mappings>
<register_mapping dwarf="0" ghidra="D0" auto_count="8"/> <!-- D0..D7 -->
<register_mapping dwarf="8" ghidra="A0" auto_count="7"/> <!-- A0..A6 -->
<register_mapping dwarf="15" ghidra="SP" stackpointer="true"/>
<register_mapping dwarf="16" ghidra="FP0" auto_count="8"/> <!-- FP0..FP7 -->
</register_mappings>
</dwarf>
@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<language_definitions>
<language processor="68000"
endian="big"
size="32"
variant="default"
version="1.1"
slafile="68040.sla"
processorspec="68000.pspec"
manualindexfile="../manuals/68000.idx"
id="68000:BE:32:default">
<description>Motorola 32-bit 68040</description>
<compiler name="default" spec="68000.cspec" id="default"/>
<external_name tool="gnu" name="m68k"/>
<external_name tool="IDA-PRO" name="68000"/>
<external_name tool="IDA-PRO" name="68040"/>
<external_name tool="IDA-PRO" name="68K"/>
<external_name tool="DWARF.register.mapping.file" name="68000.dwarf"/>
</language>
<language processor="68000"
endian="big"
size="32"
variant="MC68030"
version="1.1"
slafile="68030.sla"
processorspec="68000.pspec"
manualindexfile="../manuals/68000.idx"
id="68000:BE:32:MC68030">
<description>Motorola 32-bit 68030</description>
<compiler name="default" spec="68000.cspec" id="default"/>
<external_name tool="gnu" name="m68k:68030"/>
<external_name tool="IDA-PRO" name="68030"/>
<external_name tool="DWARF.register.mapping.file" name="68000.dwarf"/>
</language>
<language processor="68000"
endian="big"
size="32"
variant="MC68020"
version="1.1"
slafile="68020.sla"
processorspec="68000.pspec"
manualindexfile="../manuals/68000.idx"
id="68000:BE:32:MC68020">
<description>Motorola 32-bit 68020</description>
<compiler name="default" spec="68000.cspec" id="default"/>
<external_name tool="gnu" name="m68k:68020"/>
<external_name tool="IDA-PRO" name="68010"/>
<external_name tool="IDA-PRO" name="68020"/>
<external_name tool="IDA-PRO" name="68020EX"/>
<external_name tool="DWARF.register.mapping.file" name="68000.dwarf"/>
</language>
<language processor="68000"
endian="big"
size="32"
variant="Coldfire"
version="1.1"
slafile="coldfire.sla"
processorspec="68000.pspec"
manualindexfile="../manuals/68000.idx"
id="68000:BE:32:Coldfire">
<description>Motorola 32-bit Coldfire</description>
<compiler name="default" spec="68000.cspec" id="default"/>
<external_name tool="IDA-PRO" name="colfire"/>
<external_name tool="DWARF.register.mapping.file" name="68000.dwarf"/>
</language>
</language_definitions>
@@ -0,0 +1,17 @@
<opinions>
<constraint loader="Executable and Linking Format (ELF)" compilerSpecID="default">
<constraint primary="4" processor="68000" endian="big" size="32" />
</constraint>
<constraint loader="Preferred Executable Format (PEF)" compilerSpecID="default">
<constraint primary="m68k" processor="68000" endian="big" size="32" />
</constraint>
<constraint loader="Palm Pilot Program (Palm)" compilerSpecID="default">
<constraint primary="0" processor="68000" endian="big" size="32" />
</constraint>
<constraint loader="Assembler Output (AOUT)" compilerSpecID="default">
<constraint primary="1" processor="68000" endian="big" size="32" />
<constraint primary="2" processor="68000" endian="big" size="32" />
<constraint primary="200" processor="68000" endian="big" size="32" />
<constraint primary="300" processor="68000" endian="big" size="32" />
</constraint>
</opinions>
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<processor_spec>
<properties>
<property key="emulateInstructionStateModifierClass" value="ghidra.program.emulation.m68kEmulateInstructionStateModifier"/>
<property key="assemblyRating:68000:BE:32:default" value="PLATINUM"/>
</properties>
<programcounter register="PC"/>
</processor_spec>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1 @@
@include "68000.sinc"
@@ -0,0 +1,2 @@
@define MC68030 ""
@include "68000.sinc"
@@ -0,0 +1,2 @@
@define MC68040 ""
@include "68000.sinc"
@@ -0,0 +1,6 @@
# Motorola's Coldfire processor
@define COLDFIRE ""
@define MC68040 ""
@include "68000.sinc"
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<compiler_spec>
<global>
<range space="CODE"/>
<range space="INTMEM"/>
<range space="EXTMEM"/>
<range space="PORT"/>
</global>
<stackpointer register="SP" space="INTMEM" growth="positive"/>
<returnaddress>
<varnode space="stack" offset="-2" size="2"/>
</returnaddress>
<default_proto>
<prototype name="__stdcall" extrapop="-2" stackshift="-2" strategy="register">
<input>
<pentry minsize="1" maxsize="1">
<register name="A"/>
</pentry>
</input>
<output>
<pentry minsize="1" maxsize="1">
<register name="A"/>
</pentry>
</output>
<unaffected>
<register name="SP"/>
</unaffected>
</prototype>
</default_proto>
</compiler_spec>
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<language_definitions>
<language processor="8048"
endian="little"
size="16"
variant="default"
version="1.0"
slafile="8048.sla"
processorspec="8048.pspec"
manualindexfile="../manuals/8048.idx"
id="8048:LE:16:default">
<description>8048 Microcontroller Family</description>
<compiler name="default" spec="8048.cspec" id="default"/>
</language>
</language_definitions>
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<processor_spec>
<programcounter register="PC"/>
<default_symbols>
<symbol name="BANK0_R0" address="INTMEM:00"/>
<symbol name="BANK0_R1" address="INTMEM:01"/>
<symbol name="BANK0_R2" address="INTMEM:02"/>
<symbol name="BANK0_R3" address="INTMEM:03"/>
<symbol name="BANK0_R4" address="INTMEM:04"/>
<symbol name="BANK0_R5" address="INTMEM:05"/>
<symbol name="BANK0_R6" address="INTMEM:06"/>
<symbol name="BANK0_R7" address="INTMEM:07"/>
<symbol name="BANK1_R0" address="INTMEM:18"/>
<symbol name="BANK1_R1" address="INTMEM:19"/>
<symbol name="BANK1_R2" address="INTMEM:1a"/>
<symbol name="BANK1_R3" address="INTMEM:1b"/>
<symbol name="BANK1_R4" address="INTMEM:1c"/>
<symbol name="BANK1_R5" address="INTMEM:1d"/>
<symbol name="BANK1_R6" address="INTMEM:1e"/>
<symbol name="BANK1_R7" address="INTMEM:1f"/>
<symbol name="BUS" address="PORT:0"/>
<symbol name="P1" address="PORT:1"/>
<symbol name="P2" address="PORT:2"/>
<symbol name="P4" address="PORT:4"/>
<symbol name="P5" address="PORT:5"/>
<symbol name="P6" address="PORT:6"/>
<symbol name="P7" address="PORT:7"/>
<symbol name="RESET" address="CODE:0" entry="true"/>
<symbol name="EXTIRQ" address="CODE:3" entry="true"/>
<symbol name="TIMIRQ" address="CODE:7" entry="true"/>
</default_symbols>
<default_memory_blocks>
<memory_block name="REG_BANK_0" start_address="INTMEM:0" length="0x8" initialized="false"/>
<memory_block name="STACK" start_address="INTMEM:8" length="0x10" initialized="false"/>
<memory_block name="REG_BANK_1" start_address="INTMEM:18" length="0x8" initialized="false"/>
<memory_block name="INTMEM" start_address="INTMEM:20" length="0xe0" initialized="false"/>
<memory_block name="PORT" start_address="PORT:0" length="0x8" initialized="false"/>
</default_memory_blocks>
</processor_spec>
@@ -0,0 +1,539 @@
# sleigh specification file for Intel 8048
# Do not take BS into account when decompiling
@define SINGLE_REGISTER_BANK ""
# Treat R0-R7 as not memory mapped (implies SINGLE_REGISTER_BANK)
@define INTERNAL_REGISTERS ""
@ifdef INTERNAL_REGISTERS
@define SINGLE_REGISTER_BANK ""
@endif
define endian=little;
define alignment=1;
define space CODE type=ram_space size=2 default;
define space INTMEM type=ram_space size=1;
define space EXTMEM type=ram_space size=1;
define space PORT type=ram_space size=1;
define space register type=register_space size=1;
define register offset=0x00 size=1 [ A SP ];
@ifdef INTERNAL_REGISTERS
define register offset=0x10 size=1 [ R0 R1 R2 R3 R4 R5 R6 R7 ];
@endif
define register offset=0x20 size=2 [ PC ];
define register offset=0x30 size=1 [ C AC F0 F1 BS DFB ]; # single bit
################################################################
# Tokens
################################################################
define token opbyte (8)
opfull = (0,7)
oplo = (0,3)
ophi = (4,7)
rn = (0,2) dec
rnfill = (3,3)
ri = (0,0) dec
rifill = (1,3)
opaddr = (5,7)
addrfill = (4,4)
pp = (0,1) dec
xpp = (0,1) dec
ppfill = (2,3)
abit = (5,7) dec
abfill = (4,4)
dfb = (4,4)
bs = (4,4)
;
define token aopword (16)
aoplo = (0,3)
aaddrfill = (4,4)
aopaddr = (5,7)
adata = (8,15)
;
define token ImmedByte (8) data=(0,7);
define token AddrOne (8) addr8=(0,7);
@ifdef INTERNAL_REGISTERS
attach variables rn [ R0 R1 R2 R3 R4 R5 R6 R7 ];
attach variables ri [ R0 R1 ];
@else
attach names rn [ R0 R1 R2 R3 R4 R5 R6 R7 ];
attach names ri [ R0 R1 ];
@endif
attach names dfb [ MB0 MB1 ];
attach names bs [ RB0 RB1 ];
attach names pp [ BUS P1 P2 _ ];
attach names xpp [ P4 P5 P6 P7 ];
################################################################
# Pseudo Instructions
################################################################
define pcodeop nop;
define pcodeop enableExtInt;
define pcodeop enableTCntInt;
define pcodeop enableClockOutput;
define pcodeop disableExtInt;
define pcodeop disableTCntInt;
define pcodeop startTimer;
define pcodeop startEventCounter;
define pcodeop stopTimerAndEventCounter;
define pcodeop setTmr;
define pcodeop getTmr;
define pcodeop getT0;
define pcodeop getT1;
define pcodeop getTF;
define pcodeop getExtInt;
define pcodeop readPort;
define pcodeop writePort;
define pcodeop setBank;
################################################################
# Macros
################################################################
macro getPSW(reg) {
local tmp:1 = 0;
tmp[7,1] = C;
tmp[6,1] = AC;
tmp[5,1] = F0;
tmp[4,1] = BS;
tmp[3,1] = 1;
tmp[0,3] = (SP>>1)&7;
reg = tmp;
}
macro setPSW(reg) {
local tmp:1 = reg;
C = tmp[7,1];
AC = tmp[6,1];
F0 = tmp[5,1];
BS = tmp[4,1];
SP = 2*tmp[0,3] + 8;
}
macro savePSWtoPC(pc) {
pc[15,1] = C;
pc[14,1] = AC;
pc[13,1] = F0;
pc[12,1] = BS;
}
macro restorePSWfromPC(pc) {
C = pc[15,1];
AC = pc[14,1];
F0 = pc[13,1];
BS = pc[12,1];
}
macro push(v) {
*[INTMEM]:2 SP = v;
SP = SP + 2;
}
macro pop(v) {
SP = SP - 2;
v = *[INTMEM]:2 SP;
}
macro popPC(pc) {
pop(pc);
pc = pc & 0xfff;
}
macro popPCandPSW(pc) {
pop(pc);
restorePSWfromPC(pc);
pc = pc & 0xfff;
}
macro funcall(target) {
ret:2 = inst_next;
savePSWtoPC(ret);
push(ret);
call target;
}
macro add(dest, op1, op2, cy_in) {
local result:1 = op1 + op2 + cy_in;
local half_result:1 = (op1 & 0xf) + (op2 & 0xf) + cy_in;
C = carry(op1, op2) || carry(op1+op2, cy_in);
AC = (half_result > 0xf);
dest = result;
}
macro da(reg) {
local tmp:1 = reg;
local low:1 = 6*(AC || (tmp&0xf) > 9);
local cy1:1 = C || carry(tmp, low);
tmp = tmp + low;
local high:1 = 0x60*(cy1 || tmp > 0x99);
C = C || carry(tmp, high);
tmp = tmp + high;
reg = tmp;
}
macro rotc(cy, acc) {
local tmp:1 = cy;
A = acc;
C = tmp;
}
macro xch(node1, node2) {
local tmp:1 = node1;
node1 = node2;
node2 = tmp;
}
@ifdef SINGLE_REGISTER_BANK
macro regbank(r) { r = r; }
macro setbank(bs) {
BS = bs;
local tmp:1 = bs;
setBank(tmp);
}
@else
macro regbank(r) {
r = r + BS*0x18;
}
macro setbank(bs) {
BS = bs;
}
@endif
################################################################
Psw: "PSW" is epsilon { }
ExtInt: "I" is epsilon { }
TCntInt: "TCNTI" is epsilon { }
Clk: "CLK" is epsilon { }
Tmr: "T" is epsilon { }
Cnt: "CNT" is epsilon { }
TmrCnt: "TCNT" is epsilon { }
@ifdef INTERNAL_REGISTERS
Rn: rn is rn & rnfill=1 {
export rn;
}
Rind: @ri is ri & rifill=0 {
export ri;
}
@else
Rn: rn is rn & rnfill=1 {
local ptr:1 = rn; regbank(ptr); export *[INTMEM]:1 ptr;
}
Rind: @ri is ri & rifill=0 {
local ptr:1 = ri; regbank(ptr); export *[INTMEM]:1 ptr;
}
@endif
Ri: Rind is Rind {
export *[INTMEM]:1 Rind;
}
RiX: Rind is Rind {
export *[EXTMEM]:1 Rind;
}
PData: @A is A {
local addr:2 = inst_next; addr[0,7] = A; export *[CODE]:1 addr;
}
P3Data: @A is A {
local addr:2 = 0x300; addr[0,7] = A; export *[CODE]:1 addr;
}
AddrInd: PData is PData {
local addr:2 = inst_next; addr[0,7] = PData; export *[CODE]:1 addr;
}
Ab: abit is abit {
local bit:1 = (A>>abit)&1; export bit;
}
Data: "#"^data is data {
export *[const]:1 data;
}
Imm: Data is oplo=3; Data {
export Data;
}
Addr8: addr is addr8 [ addr = (inst_next $and 0xf00)+addr8; ] {
export *[CODE]:1 addr;
}
Addr12: addr is aopaddr & adata [ addr = (DFB*2048)+(aopaddr*256)+adata; ] {
export *[CODE]:1 addr;
}
Bus: "BUS" is epsilon {
local tmp:1 = 0; export *[PORT]:1 tmp;
}
Pp: pp is pp & ppfill=2 {
export *[PORT]:1 pp;
}
Xpp: xpp is xpp & ppfill=3 {
local tmp:1 = xpp+4; export *[PORT]:1 tmp;
}
Cc: "C" is ophi=15 {
export C;
}
Cc: "F0" is ophi=11 {
export F0;
}
Cc: "F1" is ophi=7 {
export F1;
}
Cc: "NC" is ophi=14 {
tmp:1 = !C; export tmp;
}
Cc: "NI" is ophi=8 {
tmp:1 = getExtInt(); tmp = !tmp; export tmp;
}
Cc: "NT0" is ophi=2 {
tmp:1 = getT0(); tmp = !tmp; export tmp;
}
Cc: "NT1" is ophi=4 {
tmp:1 = getT1(); tmp = !tmp; export tmp;
}
Cc: "NZ" is ophi=9 {
tmp:1 = A!=0; export tmp;
}
Cc: "TF" is ophi=1 {
tmp:1 = getTF(); export tmp;
}
Cc: "T0" is ophi=3 {
tmp:1 = getT0(); export tmp;
}
Cc: "T1" is ophi=5 {
tmp:1 = getT1(); export tmp;
}
Cc: "Z" is ophi=12 {
tmp:1 = A==0; export tmp;
}
# Conventience tables for opcodes taking both Rn and Ri (and Imm)
Rni: Rn is Rn {
export Rn;
}
Rni: Ri is Ri {
export Ri;
}
RniI: Rni is Rni {
export Rni;
}
RniI: Imm is Imm {
export Imm;
}
:ADD A,Rni is ophi=6 & (rnfill=1 | rifill=0) & A & Rni {
add(A,A,Rni,0);
}
:ADD A,Imm is (ophi=0 & A)... & Imm {
add(A,A,Imm,0);
}
:ADDC A,Rni is ophi=7 & A & (rnfill=1 | rifill=0) & Rni {
add(A,A,Rni,C);
}
:ADDC A,Imm is (ophi=1 & A)... & Imm {
add(A,A,Imm,C);
}
:ANL A,RniI is (ophi=5 & (rnfill=1 | rifill=0 | oplo=3) & A)... & RniI {
A = A & RniI;
}
:ANL Pp,Data is ophi=9 & ppfill=2 & Pp; Data {
Pp = Pp & Data;
}
:ANLD Xpp,A is ophi=9 & ppfill=3 & Xpp & A {
Xpp = Xpp & (A & 0xf);
}
:CALL Addr12 is aopaddr & aaddrfill=1 & aoplo=4 & Addr12 {
funcall(Addr12);
}
:CLR A is ophi=2 & oplo=7 & A {
A = 0;
}
:CLR C is ophi=9 & oplo=7 & C {
C = 0;
}
:CLR F0 is ophi=8 & oplo=5 & F0 {
F0 = 0;
}
:CLR F1 is ophi=10 & oplo=5 & F1 {
F1 = 0;
}
:CPL A is ophi=3 & oplo=7 & A {
A = ~A;
}
:CPL C is ophi=10 & oplo=7 & C {
C = !C;
}
:CPL F0 is ophi=9 & oplo=5 & F0 {
F0 = !F0;
}
:CPL F1 is ophi=11 & oplo=5 & F1 {
F1 = !F1;
}
:DA A is ophi=5 & oplo=7 & A {
da(A);
}
:DEC A is ophi=0 & oplo=7 & A {
A = A - 1;
}
:DEC Rn is ophi=12 & Rn {
Rn = Rn - 1;
}
:DIS ExtInt is ophi=1 & oplo=5 & ExtInt {
disableExtInt();
}
:DIS TCntInt is ophi=3 & oplo=5 & TCntInt {
disableTCntInt();
}
:DJNZ Rn,Addr8 is ophi=14 & Rn; Addr8 {
Rn = Rn - 1; if(Rn != 0) goto Addr8;
}
:EN ExtInt is ophi=0 & oplo=5 & ExtInt {
enableExtInt();
}
:EN TCntInt is ophi=2 & oplo=5 & TCntInt {
enableTCntInt();
}
:ENT0 Clk is ophi=7 & oplo=5 & Clk {
enableClockOutput();
}
:IN A,Pp is ophi=0 & pp!=0 & A & Pp {
A = Pp;
}
:INC A is ophi=1 & oplo=7 & A {
A = A + 1;
}
:INC Rni is ophi=1 & (rnfill=1 | rifill=0) & Rni {
Rni = Rni + 1;
}
:INS A,Bus is ophi=0 & oplo=8 & A & Bus {
A = Bus;
}
:JB^Ab Addr8 is oplo=2 & opaddr & abfill=1 & Ab; Addr8 {
if(Ab) goto Addr8;
}
:J^Cc Addr8 is ophi & oplo=6 & Cc; Addr8 {
if(Cc) goto Addr8;
}
:JMP Addr12 is aopaddr & aaddrfill=0 & aoplo=4 & Addr12 {
goto Addr12;
}
:JMPP AddrInd is ophi=11 & oplo=3 & AddrInd {
goto AddrInd;
}
:MOV A,Imm is (ophi=2 & A)... & Imm {
A = Imm;
}
:MOV A,Psw is ophi=12 & oplo=7 & A & Psw {
getPSW(A);
}
:MOV A,Rni is ophi=15 & A & (rnfill=1 | rifill=0) & Rni {
A = Rni;
}
:MOV A,Tmr is ophi=4 & oplo=2 & A & Tmr {
A = getTmr();
}
:MOV Psw,A is ophi=13 & oplo=7 & Psw & A {
setPSW(A);
}
:MOV Rni,A is ophi=10 & (rnfill=1 | rifill=0) & Rni & A {
Rni = A;
}
:MOV Rni,Data is ophi=11 & (rnfill=1 | rifill=0) & Rni; Data {
Rni = Data;
}
:MOV Tmr,A is ophi=6 & oplo=2 & Tmr & A {
setTmr(A);
}
:MOVD A,Xpp is ophi=0 & Xpp & A {
A = (Xpp & 0xf);
}
:MOVD Xpp,A is ophi=3 & Xpp & A {
Xpp = (A & 0xf);
}
:MOVP A,PData is ophi=10 & oplo=3 & A & PData {
A = PData;
}
:MOVP3 A,P3Data is ophi=14 & oplo=3 & A & P3Data {
A = P3Data;
}
:MOVX A,RiX is ophi=8 & A & RiX {
A = RiX;
}
:MOVX RiX,A is ophi=9 & RiX & A {
RiX = A;
}
:NOP is ophi=0 & oplo=0 {
nop();
}
:ORL A,RniI is (ophi=4 & (rnfill=1 | rifill=0 | oplo=3) & A)... & RniI {
A = A | RniI;
}
:ORL Pp,Data is ophi=8 & Pp; Data {
Pp = Pp | Data;
}
:ORLD Xpp,A is ophi=8 & Xpp & A {
Xpp = Xpp | (A & 0xf);
}
:OUTL Bus,A is ophi=0 & oplo=2 & Bus & A {
Bus = A;
}
:OUTL Pp,A is ophi=3 & pp!=0 & Pp & A {
Pp = A;
}
:RET is ophi=8 & oplo=3 {
pc:2 = 0; popPC(pc); return[pc];
}
:RETR is ophi=9 & oplo=3 {
pc:2 = 0; popPCandPSW(pc); return[pc];
}
:RL A is ophi=14 & oplo=7 & A {
A = (A<<1) | (A>>7);
}
:RLC A is ophi=15 & oplo=7 & A {
rotc((A&0x80)>>7, (A<<1)|C);
}
:RR A is ophi=7 & oplo=7 & A {
A = (A>>1) | (A<<7);
}
:RRC A is ophi=6 & oplo=7 & A {
rotc(A&1, (A>>1)|(C<<7));
}
:SEL dfb is (ophi=14 | ophi=15) & oplo=5 & dfb {
DFB = dfb;
}
:SEL bs is (ophi=12 | ophi=13) & oplo=5 & bs {
setbank(bs);
}
:STOP TmrCnt is ophi=6 & oplo=5 & TmrCnt {
stopTimerAndEventCounter();
}
:STRT Cnt is ophi=4 & oplo=5 & Cnt {
startEventCounter();
}
:STRT Tmr is ophi=5 & oplo=5 & Tmr {
startTimer();
}
:SWAP A is ophi=4 & oplo=7 & A {
A = (A<<4)|(A>>4);
}
:XCH A,Rni is ophi=2 & (rnfill=1 | rifill=0) & A & Rni {
xch(A, Rni);
}
:XCHD A,Ri is ophi=3 & A & Ri {
xch(A[0,4], Ri[0,4]);
}
:XRL A,RniI is (ophi=13 & (rnfill=1 | rifill=0 | oplo=3) & A)... & RniI {
A = A ^ RniI;
}
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<compiler_spec>
<global>
<range space="RAM"/>
<range space="SFR"/>
<range space="BITS"/>
</global>
<stackpointer register="SPX" space="RAM" growth="positive"/>
<default_proto>
<prototype name="__stdcall" extrapop="-2" stackshift="-2">
<input>
<pentry minsize="1" maxsize="1">
<register name="R0"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="R1"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="R2"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="R3"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="R4"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="R5"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="R6"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="R7"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="ACC"/>
</pentry>
</input>
<output>
<pentry minsize="1" maxsize="1">
<register name="ACC"/>
</pentry>
</output>
<unaffected>
<register name="SPX"/>
</unaffected>
<localrange>
<range space="stack" first="0x0" last="0xfffc"/>
</localrange>
</prototype>
</default_proto>
</compiler_spec>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,662 @@
# 80251 Instructions
# NOTE! 80251 implementation is preliminary and has not tested !!
define token srcDestByte (8)
rm47 = (4,7)
rm47_d1 = (4,7)
rm47_d2 = (4,7)
rm03 = (0,3)
wrj47 = (4,7)
wrj47_d1 = (4,7)
wrj47_d2 = (4,7)
wrj03 = (0,3)
drk47 = (4,7)
drk03 = (0,3)
# constraint bits
d7 = (7,7)
d57 = (5,7)
d47 = (4,7)
s3 = (3,3)
s23 = (2,3)
s13 = (1,3)
s03 = (0,3)
s1 = (1,1)
s0 = (0,0)
short01 = (0,1)
bit02 = (0,2)
;
define token srcDestByte2 (8)
rm47_ = (4,7)
rm03_ = (0,3)
wrj47_ = (4,7)
wrj03_ = (0,3)
drk47_ = (4,7)
drk03_ = (0,3)
# constraint bits
d7_ = (7,7)
d57_ = (5,7)
s3_ = (3,3)
s13_ = (1,3)
s03_ = (0,3)
;
define token AddrThree (24)
addr24 = (0,23)
;
define token ImmedThree (24)
data24 = (0,23)
;
attach values short01 [ 1 2 4 _ ];
attach variables [ rm47 rm03 rm47_ rm03_ ] [
R0 R1 R2 R3 R4 R5 R6 R7
R8 R9 B ACC R12 R13 R14 R15
];
attach variables [ rm47_d1 ] [
R0 R0 R2 R2 R4 R3 R6 R6
R8 R8 B B R12 R12 R14 R14
];
attach variables [ rm47_d2 ] [
R1 R1 R3 R3 R5 R5 R7 R7
R9 R9 ACC ACC R13 R13 R15 R15
];
attach variables [ wrj47 wrj03 wrj47_ wrj03_ ] [
WR0 WR2 WR4 WR6 WR8 AB WR12 WR14
WR16 WR18 WR20 WR22 WR24 WR26 WR28 WR30
];
attach variables [ wrj47_d1 ] [
WR0 WR0 WR4 WR4 WR8 WR8 WR12 WR12
WR16 WR16 WR20 WR20 WR24 WR24 WR28 WR28
];
attach variables [ wrj47_d2 ] [
WR2 WR2 WR6 WR6 AB AB WR14 WR14
WR18 WR18 WR22 WR22 WR26 WR26 WR30 WR30
];
# NOTE: must use constraints DRK, DRKD and DRKS
attach variables [ drk47 drk03 drk47_ drk03_ ] [
DR0 DR4 DR8 DR12 DR16 DR20 DR24 DR28
DPX SPX _ _ _ _ _ _
];
@define DRK47 "drk47 & (d7=0 | d57=4)" # constraint for using drk47
@define DRK03 "drk03 & (s3=0 | s13=4)" # constraint for using drk03
@define DRK47_ "drk47_ & (d7_=0 | d57_=4)" # constraint for using drk47_
AtWRjb: "@"^wrj47 is wrj47 { ptr:3 = zext(wrj47); export *:1 ptr; }
AtWRjw: "@"^wrj47 is wrj47 { ptr:3 = zext(wrj47); export *:2 ptr; }
# NOTE: be sure to use the ATDRK constraint on the constructor
AtDRkb: "@"^drk47 is drk47 { ptr:3 = drk47:3; export *:1 ptr; }
AtDRkw: "@"^drk47 is drk47 { ptr:3 = drk47:3; export *:2 ptr; }
AtDRkt: "@"^drk47 is drk47 { ptr:3 = drk47:3; export *:3 ptr; }
@define ATDRK "(d7=0 | d57=4)"
AtWRj47Dis16b: "@"^wrj47^"+"^data16 is wrj47; data16 { ptr:3 = zext(wrj47) + data16; export *:1 ptr; }
AtWRj47Dis16w: "@"^wrj47^"+"^data16 is wrj47; data16 { ptr:3 = zext(wrj47) + data16; export *:2 ptr; }
AtWRj03Dis16b: "@"^wrj03^"+"^data16 is wrj03; data16 { ptr:3 = zext(wrj03) + data16; export *:1 ptr; }
AtWRj03Dis16w: "@"^wrj03^"+"^data16 is wrj03; data16 { ptr:3 = zext(wrj03) + data16; export *:2 ptr; }
AtDRk47Dis24b: "@"^drk47^"+"^data24 is drk47; data24 { ptr:3 = drk47:3 + data24; export *:1 ptr; }
AtDRk47Dis24w: "@"^drk47^"+"^data24 is drk47; data24 { ptr:3 = drk47:3 + data24; export *:2 ptr; }
AtDRk03Dis24b: "@"^drk03^"+"^data24 is drk03; data24 { ptr:3 = drk03:3 + data24; export *:1 ptr; }
AtDRk03Dis24w: "@"^drk03^"+"^data24 is drk03; data24 { ptr:3 = drk03:3 + data24; export *:2 ptr; }
# TODO: Verify dir8 access restriction for word/dword accesses !!
Direct8w: mainreg is bank=0 & mainreg { export *:2 mainreg; }
Direct8w: Direct is bank=1 & Direct { tmp:2 = zext(Direct); export tmp; }
# TODO: The dir16 mode does not map into the SFR's - is this correct ??
Direct16b: addr16 is addr16 { export *:1 addr16; }
Direct16w: addr16 is addr16 { export *:2 addr16; }
Direct16d: addr16 is addr16 { export *:4 addr16; }
Data16x0: "#"data16 is data16 { export *[const]:4 data16; }
Data16x1: "#"val is data16 [ val = 0xffff0000 + data16; ] { export *[const]:4 val; }
Addr24: addr24 is addr24 { export *:1 addr24; }
# NOTE: use SHORT constraint
Short: "#"^short01 is short01 { export *[const]:1 short01; }
@define SHORT "Short & (s0=0 | s1=0)"
#TODO: Figure out new bit addressing for 251 ...
xBitByteAddr: is bitaddr8 { export *:1 bitaddr8; }
xBitAddr: bitaddr^"."^bit02 is bit02; bitaddr8 [ bitaddr = (bitaddr8 << 3) + bit02; ] { export *[BITS]:1 bitaddr; }
xBitAddr2: "/"^bitaddr^"."^bit02 is bit02; bitaddr8 [ bitaddr = (bitaddr8 << 3) + bit02; ] { export *[BITS]:1 bitaddr; }
macro push24(val) {
al:1 = val:1;
ah:1 = val(1);
ax:1 = val(2);
ptr:3 = SPX:3;
ptr = ptr + 1;
*[RAM]:1 ptr = al;
ptr = ptr + 1;
*[RAM]:1 ptr = ah;
ptr = ptr + 1;
*[RAM]:1 ptr = ax;
SPX = SPX + 3;
}
macro pop24(val) {
SPX = SPX - 2;
ptr:3 = SPX:3;
al:1 = *[RAM]:1 ptr;
ah:1 = *[RAM]:1 (ptr+1);
ax:1 = *[RAM]:1 (ptr+2);
SPX = SPX - 1;
val = (zext(ax) << 16) | (zext(ah) << 8) | zext(al);
}
# s s s s Binary representation of m or md
# S S S S Binary representation of ms
# t t t t Binary representation of j or jd
# T T T T Binary representation of js
# u u u u Binary representation of k or kd
# U U U U Binary representation of ks
# NOTE: >>>> Find MCS251 instructions by searching for "Binary Mode = [A5][Encoding]" in PDF manual <<<<
# NOTE: All instructions should include the $(GROUP3) pattern prefix
# ADD Rmd,Rms
:ADD rm47,rm03 is $(GROUP3) & ophi=2 & oplo=12; rm47 & rm03 { addflags(rm47,rm03); rm47 = rm47 + rm03; resultflags(rm47); }
# ADD WRjd,WRjs
:ADD wrj47,wrj03 is $(GROUP3) & ophi=2 & oplo=13; wrj47 & wrj03 { addflags(wrj47,wrj03); wrj47 = wrj47 + wrj03; resultflags(wrj47); }
# ADD DRkd,DRks
:ADD drk47,drk03 is $(GROUP3) & ophi=2 & oplo=15; $(DRK47) & $(DRK03) { addflags(drk47,drk03); drk47 = drk47 + drk03; resultflags(drk47); }
# ADD Rm,#data
:ADD rm47,Data is $(GROUP3) & ophi=2 & oplo=14; rm47 & s03=0; Data { addflags(rm47,Data); rm47 = rm47 + Data; resultflags(rm47); }
# ADD WRj,#data16
:ADD wrj47,Data16 is $(GROUP3) & ophi=2 & oplo=14; wrj47 & s03=4; Data16 { addflags(wrj47,Data16); wrj47 = wrj47 + Data16; resultflags(wrj47); }
# ADD DRk,#0data16
:ADD drk47,Data16x0 is $(GROUP3) & ophi=2 & oplo=14; $(DRK47) & s03=8; Data16x0 { addflags(drk47,Data16x0); drk47 = drk47 + Data16x0; resultflags(drk47); }
# ADD Rm,dir8
:ADD rm47,Direct is $(GROUP3) & ophi=2 & oplo=14; rm47 & s03=1; Direct { addflags(rm47,Direct); rm47 = rm47 + Direct; resultflags(rm47); }
# ADD WRj,dir8
:ADD wrj47,Direct8w is $(GROUP3) & ophi=2 & oplo=14; wrj47 & s03=5; Direct8w { addflags(wrj47,Direct8w); wrj47 = wrj47 + Direct8w; resultflags(wrj47); }
# ADD Rm,dir16
:ADD rm47,Direct16b is $(GROUP3) & ophi=2 & oplo=14; rm47 & s03=3; Direct16b { addflags(rm47,Direct16b); rm47 = rm47 + Direct16b; resultflags(rm47); }
# ADD WRj,dir16
:ADD wrj47,Direct16w is $(GROUP3) & ophi=2 & oplo=14; wrj47 & s03=7; Direct16w { addflags(wrj47,Direct16w); wrj47 = wrj47 + Direct16w; resultflags(wrj47); }
# ADD Rm,@WRj
:ADD rm47_,AtWRjb is $(GROUP3) & ophi=2 & oplo=14; AtWRjb & s03=9; rm47_ & s03_=0 { addflags(rm47_,AtWRjb); rm47_ = rm47_ + AtWRjb; resultflags(rm47_); }
# ADD Rm,@DRk
:ADD rm47_,AtDRkb is $(GROUP3) & ophi=2 & oplo=14; $(ATDRK) & AtDRkb & s03=11; rm47_ & s03_=0 { addflags(rm47_,AtDRkb); rm47_ = rm47_ + AtDRkb; resultflags(rm47_); }
# ANL Rmd,Rms
:ANL rm47,rm03 is $(GROUP3) & ophi=5 & oplo=12; rm47 & rm03 { rm47 = rm47 & rm03; resultflags(rm47); }
# ANL WRjd,WRjs
:ANL wrj47,wrj03 is $(GROUP3) & ophi=5 & oplo=13; wrj47 & wrj03 { wrj47 = wrj47 & wrj03; resultflags(wrj47); }
# ANL Rm,#data
:ADD rm47,Data is $(GROUP3) & ophi=5 & oplo=14; rm47 & s03=0; Data { rm47 = rm47 & Data; resultflags(rm47); }
# ANL WRj,#data16
:ANL wrj47,Data16 is $(GROUP3) & ophi=5 & oplo=14; wrj47 & s03=4; Data16 { wrj47 = wrj47 & Data16; resultflags(wrj47); }
# ANL Rm,dir8
:ANL rm47,Direct is $(GROUP3) & ophi=5 & oplo=14; rm47 & s03=1; Direct { rm47 = rm47 & Direct; resultflags(rm47); }
# ANL WRj,dir8
:ANL wrj47,Direct8w is $(GROUP3) & ophi=5 & oplo=14; wrj47 & s03=5; Direct8w { wrj47 = wrj47 & Direct8w; resultflags(wrj47); }
# ANL Rm,dir16
:ANL rm47,Direct16b is $(GROUP3) & ophi=5 & oplo=14; rm47 & s03=3; Direct16b { rm47 = rm47 & Direct16b; resultflags(rm47); }
# ANL WRj,dir16
:ANL wrj47,Direct16w is $(GROUP3) & ophi=5 & oplo=14; wrj47 & s03=7; Direct16w { wrj47 = wrj47 & Direct16w; resultflags(wrj47); }
# ANL Rm,@WRj
:ANL rm47_,AtWRjb is $(GROUP3) & ophi=5 & oplo=14; AtWRjb & s03=9; rm47_ & s03_=0 { rm47_ = rm47_ & AtWRjb; resultflags(rm47_); }
# ANL Rm,@DRk
:ANL rm47_,AtDRkb is $(GROUP3) & ophi=5 & oplo=14; $(ATDRK) & AtDRkb & s03=11; rm47_ & s03_=0 { rm47_ = rm47_ & AtDRkb; resultflags(rm47_); }
# ANL C,bit
:ANL "CY",xBitAddr is $(GROUP3) & ophi=10 & oplo=9; (d47=8 & s3=0 & bit02; xBitByteAddr) & xBitAddr { $(CY)=$(CY)& ((xBitByteAddr>>bit02)&1); resultflags(xBitByteAddr); }
# ANL C,/bit
:ANL "CY",xBitAddr2 is $(GROUP3) & ophi=10 & oplo=9; (d47=15 & s3=0 & bit02; xBitByteAddr) & xBitAddr2 { $(CY)=$(CY)& (~((xBitByteAddr>>bit02)&1)); resultflags(xBitByteAddr); }
# CLR bit
:CLR xBitAddr is $(GROUP3) & ophi=10 & oplo=9; (d47=12 & s3=0 & bit02; xBitByteAddr) & xBitAddr { tmp:1 = ~(1<<bit02); xBitByteAddr = xBitByteAddr & tmp; resultflags(xBitByteAddr); }
# CMP Rmd,Rms
:CMP rm47,rm03 is $(GROUP3) & ophi=11 & oplo=12; rm47 & rm03 { subflags(rm47,rm03); tmp:1 = rm47 - rm03; resultflags(tmp); }
# CMP WRjd,WRjs
# NOTE: Encoding in manual conflicts with CMP WRj,#data (ophi=14), modified for consistency with similar insrtuctions (e.g., ADD, SUB)
:CMP wrj47,wrj03 is $(GROUP3) & ophi=11 & oplo=13; wrj47 & wrj03 { subflags(wrj47,wrj03); tmp:2 = wrj47 - wrj03; resultflags(tmp); }
# CMP DRkd,DRks
:CMP drk47,drk03 is $(GROUP3) & ophi=11 & oplo=15; $(DRK47) & $(DRK03) { subflags(drk47,drk03); tmp:4 = drk47 - drk03; resultflags(tmp); }
# CMP Rm,#data
:CMP rm47,Data is $(GROUP3) & ophi=11 & oplo=14; rm47 & s03=0; Data { subflags(rm47,Data); tmp:1 = rm47 - Data; resultflags(tmp); }
# CMP WRj,#data16
:CMP wrj47,Data16 is $(GROUP3) & ophi=11 & oplo=14; wrj47 & s03=4; Data16 { subflags(wrj47,Data16); tmp:2 = wrj47 - Data16; resultflags(tmp); }
# CMP DRk,#0data16
:CMP drk47,Data16x0 is $(GROUP3) & ophi=11 & oplo=14; $(DRK47) & s03=8; Data16x0 { subflags(drk47,Data16x0); tmp:4 = drk47 - Data16x0; resultflags(tmp); }
# CMP DRk,#1data16
:CMP drk47,Data16x1 is $(GROUP3) & ophi=11 & oplo=14; $(DRK47) & s03=12; Data16x1 { subflags(drk47,Data16x1); tmp:4 = drk47 - Data16x1; resultflags(tmp); }
# CMP Rm,dir8
:CMP rm47,Direct is $(GROUP3) & ophi=11 & oplo=14; rm47 & s03=1; Direct { subflags(rm47,Direct); tmp:1 = rm47 - Direct; resultflags(tmp); }
# CMP WRj,dir8
:CMP wrj47,Direct8w is $(GROUP3) & ophi=11 & oplo=14; wrj47 & s03=5; Direct8w { subflags(wrj47,Direct8w); tmp:2 = wrj47 - Direct8w; resultflags(tmp); }
# CMP Rm,dir16
:CMP rm47,Direct16b is $(GROUP3) & ophi=11 & oplo=14; rm47 & s03=3; Direct16b { subflags(rm47,Direct16b); tmp:1 = rm47 - Direct16b; resultflags(tmp); }
# CMP WRj,dir16
:CMP wrj47,Direct16w is $(GROUP3) & ophi=11 & oplo=14; wrj47 & s03=7; Direct16w { subflags(wrj47,Direct16w); tmp:2 = wrj47 - Direct16w; resultflags(tmp); }
# CMP Rm,@WRj
:CMP rm47_,AtWRjb is $(GROUP3) & ophi=11 & oplo=14; AtWRjb & s03=9; rm47_ & s03_=0 { subflags(rm47_,AtWRjb); tmp:1 = rm47_ - AtWRjb; resultflags(tmp); }
# CMP Rm,@DRk
:CMP rm47_,AtDRkb is $(GROUP3) & ophi=11 & oplo=14; $(ATDRK) & AtDRkb & s03=11; rm47_ & s03_=0 { subflags(rm47_,AtDRkb); tmp:1 = rm47_ - AtDRkb; resultflags(tmp); }
# CPL bit
:CPL xBitAddr is $(GROUP3) & ophi=10 & oplo=9; (d47=11 & s3=0 & bit02; xBitByteAddr) & xBitAddr { tmp:1 = ~(1<<bit02); xBitByteAddr = xBitByteAddr ^ tmp; resultflags(xBitByteAddr); }
# DEC Rm,#short
# NOTE: Encoding in manual conflicts with DEC WRj,#short (s23=1), modified for consistency with similar insrtuctions (e.g., DEC)
:DEC rm47,Short is $(GROUP3) & ophi=1 & oplo=11; rm47 & s23=0 & $(SHORT) { subflags(rm47,Short); rm47 = rm47 - Short; resultflags(rm47); }
# DEC WRj,#short
:DEC wrj47,Short is $(GROUP3) & ophi=1 & oplo=11; wrj47 & s23=1 & $(SHORT) { val:2 = zext(Short); subflags(wrj47,val); wrj47 = wrj47 - val; resultflags(wrj47); }
# DEC DRk,#short
:DEC drk47,Short is $(GROUP3) & ophi=1 & oplo=11; $(DRK47) & s23=3 & $(SHORT) { val:4 = zext(Short); subflags(drk47,val); drk47 = drk47 - val; resultflags(drk47); }
# DIV Rmd,Rms
:DIV rm47,rm03 is $(GROUP3) & ophi=8 & oplo=12; rm47 & rm47_d1 & rm47_d2 & rm03 { rm47_d2 = rm47 / rm03; rm47_d1 = rm47 % rm03; resultflags(rm47_d2); }
# DIV WRjd,WRjs
:DIV wrj47,wrj03 is $(GROUP3) & ophi=8 & oplo=13; wrj47 & wrj47_d1 & wrj47_d2 & wrj03 { wrj47_d2 = wrj47 / wrj03; wrj47_d1 = wrj47 % wrj03; resultflags(wrj47_d2); }
# ECALL addr24
:ECALL Addr24 is $(GROUP3) & ophi=9 & oplo=10; Addr24 { ptr:3 = inst_next; push24(ptr); call Addr24; }
# ECALL @DRk
:ECALL AtDRkt is $(GROUP3) & ophi=9 & oplo=9; $(ATDRK) & AtDRkt & s03=8 { ptr:3 = inst_next; push24(ptr); call [AtDRkt]; }
# EJMP addr24
:EJMP Addr24 is $(GROUP3) & ophi=8 & oplo=10; Addr24 { goto Addr24; }
# EJMP @DRk
:EJMP AtDRkt is $(GROUP3) & ophi=8 & oplo=9; $(ATDRK) & AtDRkt & s03=8 { goto [AtDRkt]; }
# ERET
:ERET is $(GROUP3) & ophi=10 & oplo=10 { pc:3 = 0; pop24(pc); return [pc]; }
# INC Rm,#short
:INC rm47,Short is $(GROUP3) & ophi=0 & oplo=11; rm47 & s23=0 & $(SHORT) { addflags(rm47,Short); rm47 = rm47 + Short; resultflags(rm47); }
# INC WRj,#short
:INC wrj47,Short is $(GROUP3) & ophi=0 & oplo=11; wrj47 & s23=1 & $(SHORT) { val:2 = zext(Short); addflags(wrj47,val); wrj47 = wrj47 + val; resultflags(wrj47); }
# INC DRk,#short
:INC drk47,Short is $(GROUP3) & ophi=0 & oplo=11; $(DRK47) & s23=3 & $(SHORT) { val:4 = zext(Short); addflags(drk47,val); drk47 = drk47 + val; resultflags(drk47); }
# JB bit,rel
:JB xBitAddr,Rel8 is $(GROUP3) & ophi=10 & oplo=9; (d47=2 & s3=0 & bit02; xBitByteAddr) & xBitAddr; Rel8 { if (((xBitByteAddr>>bit02)&1) == 1:1) goto Rel8; }
# JBC bit,rel
:JBC xBitAddr,Rel8 is $(GROUP3) & ophi=10 & oplo=9; (d47=1 & s3=0 & bit02; xBitByteAddr) & xBitAddr; Rel8 { tmp:1 = 1<<bit02; if ((xBitByteAddr & tmp)==0) goto inst_next; xBitByteAddr = xBitByteAddr & ~tmp; goto Rel8; }
# JE rel
:JE Rel8 is $(GROUP3) & ophi=6 & oplo=8; Rel8 { if ($(Z)==1) goto Rel8; }
# JG rel
:JG Rel8 is $(GROUP3) & ophi=3 & oplo=8; Rel8 { if ($(Z)==0 && $(CY)==0) goto Rel8; }
# JLE rel
:JLE Rel8 is $(GROUP3) & ophi=2 & oplo=8; Rel8 { if ($(Z)==1 || $(CY)==1) goto Rel8; }
# JNB bit,rel
:JNB xBitAddr,Rel8 is $(GROUP3) & ophi=10 & oplo=9; (d47=3 & s3=0 & bit02; xBitByteAddr) & xBitAddr; Rel8 { if (((xBitByteAddr>>bit02)&1)==0:1) goto Rel8; }
# JNE rel
:JNE Rel8 is $(GROUP3) & ophi=7 & oplo=8; Rel8 { if ($(Z)==0) goto Rel8; }
# JSG rel
:JSG Rel8 is $(GROUP3) & ophi=1 & oplo=8; Rel8 { if ($(Z)==0 && $(N)==$(OV)) goto Rel8; }
# JSGE rel
:JSGE Rel8 is $(GROUP3) & ophi=5 & oplo=8; Rel8 { if ($(N)==$(OV)) goto Rel8; }
# JSL rel
:JSL Rel8 is $(GROUP3) & ophi=4 & oplo=8; Rel8 { if ($(N)!=$(OV)) goto Rel8; }
# JSLE rel
:JSLE Rel8 is $(GROUP3) & ophi=0 & oplo=8; Rel8 { if ($(Z)==1 || $(N)!=$(OV)) goto Rel8; }
# LCALL @WRj
:LCALL AtWRjw is $(GROUP3) & ophi=9 & oplo=9; AtWRjw & s03=4 { ptr:3 = inst_next; push16(ptr:2); pc:3 = (ptr & 0xff0000) + zext(AtWRjw); call [pc]; }
# LJMP @WRj
:LJMP AtWRjw is $(GROUP3) & ophi=8 & oplo=9; AtWRjw & s03=4 { ptr:3 = inst_next; pc:3 = (ptr & 0xff0000) + zext(AtWRjw); goto [pc]; }
# MOV Rmd,Rms
:MOV rm47,rm03 is $(GROUP3) & ophi=7 & oplo=12; rm47 & rm03 { rm47 = rm03; }
# MOV WRjd,WRjs
:MOV wrj47,wrj03 is $(GROUP3) & ophi=7 & oplo=13; wrj47 & wrj03 { wrj47 = wrj03; }
# MOV DRkd,DRks
:MOV drk47,drk03 is $(GROUP3) & ophi=7 & oplo=15; drk47 & drk03 { drk47 = drk03; }
# MOV Rm,#data
:MOV rm47,Data is $(GROUP3) & ophi=7 & oplo=14; rm47 & s03=0; Data { rm47 = Data; }
# MOV WRj,#data16
:MOV wrj47,Data16 is $(GROUP3) & ophi=7 & oplo=14; wrj47 & s03=4; Data16 { wrj47 = Data16; }
# MOV DRk,#0data16
:MOV drk47,Data16x0 is $(GROUP3) & ophi=7 & oplo=14; drk47 & s03=8; Data16x0 { drk47 = Data16x0; }
# MOV DRk,#1data16
:MOV drk47,Data16x1 is $(GROUP3) & ophi=7 & oplo=14; drk47 & s03=12; Data16x1 { drk47 = Data16x1; }
# MOV Rm,dir8
:MOV rm47,Direct is $(GROUP3) & ophi=7 & oplo=14; rm47 & s03=1; Direct { rm47 = Direct; }
# MOV WRj,dir8
:MOV wrj47,Direct8w is $(GROUP3) & ophi=7 & oplo=14; wrj47 & s03=5; Direct8w { wrj47 = Direct8w; }
# MOV DRk,dir8
:MOV drk47,Direct8w is $(GROUP3) & ophi=7 & oplo=14; drk47 & s03=13; Direct8w { drk47 = zext(Direct8w); }
# MOV Rm,dir16
:MOV rm47,Direct16b is $(GROUP3) & ophi=7 & oplo=14; rm47 & s03=3; Direct16b { rm47 = Direct16b; }
# MOV WRj,dir16
:MOV wrj47,Direct16w is $(GROUP3) & ophi=7 & oplo=14; wrj47 & s03=7; Direct16w { wrj47 = Direct16w; }
# MOV DRk,dir16
:MOV drk47,Direct16d is $(GROUP3) & ophi=7 & oplo=14; drk47 & s03=15; Direct16d { drk47 = Direct16d; }
# MOV Rm,@WRj
:MOV rm47_,AtWRjb is $(GROUP3) & ophi=7 & oplo=14; AtWRjb & s03=9; rm47_ & s03_=0 { rm47_ = AtWRjb; }
# MOV Rm,@DRk
:MOV rm47_,AtDRkb is $(GROUP3) & ophi=7 & oplo=14; $(ATDRK) & AtDRkb & s03=11; rm47_ & s03_=0 { rm47_ = AtDRkb; }
# MOV WRjd,@WRjs
:MOV wrj47_,AtWRjw is $(GROUP3) & ophi=0 & oplo=11; AtWRjw & s03=8; wrj47_ & s03_=0 { wrj47_ = AtWRjw; }
# MOV WRj,@DRk
:MOV wrj47_,AtDRkw is $(GROUP3) & ophi=0 & oplo=11; $(ATDRK) & AtDRkw & s03=10; wrj47_ & s03_=0 { wrj47_ = AtDRkw; }
# MOV dir8,Rm
:MOV Direct,rm47 is $(GROUP3) & ophi=7 & oplo=10; rm47 & s03=1; Direct { Direct = rm47; }
# MOV dir8,WRj
# TODO: !! Verify direct byte write restriction to SFR registers
:MOV Direct8w,wrj47 is $(GROUP3) & ophi=7 & oplo=10; wrj47 & s03=5; bank=0 & Direct8w { Direct8w = wrj47; }
:MOV Direct,wrj47 is $(GROUP3) & ophi=7 & oplo=10; wrj47 & s03=5; bank=1 & Direct { Direct = wrj47:1; }
# MOV dir8,DRk
# TODO: !! Verify byte/word write restriction to internal memory (00-7f)
# TODO: !! Verify byte write restriction to SFR registers
:MOV Direct8w,drk47 is $(GROUP3) & ophi=7 & oplo=10; $(DRK47) & s03=13; bank=0 & Direct8w { Direct8w = drk47:2; }
:MOV Direct,drk47 is $(GROUP3) & ophi=7 & oplo=10; $(DRK47) & s03=13; bank=1 & Direct { Direct = drk47:1; }
# MOV dir16,Rm
:MOV Direct16b,rm47 is $(GROUP3) & ophi=7 & oplo=10; rm47 & s03=3; Direct16b { Direct16b = rm47; }
# MOV dir16,WRj
:MOV Direct16w,wrj47 is $(GROUP3) & ophi=7 & oplo=10; wrj47 & s03=7; Direct16w { Direct16w = wrj47; }
# MOV dir16,DRk
:MOV Direct16d,drk47 is $(GROUP3) & ophi=7 & oplo=10; $(DRK47) & s03=15; Direct16d { Direct16d = drk47; }
# MOV @WRj,Rm
:MOV AtWRjb,rm47_ is $(GROUP3) & ophi=7 & oplo=10; AtWRjb & s03=9; rm47_ & s03_=0 { AtWRjb = rm47_; }
# MOV @DRk,Rm
:MOV AtDRkb,rm47_ is $(GROUP3) & ophi=7 & oplo=10; $(ATDRK) & AtDRkb & s03=11; rm47_ & s03_=0 { AtDRkb = rm47_; }
# MOV @WRjd,WRjs
:MOV AtWRjw,wrj47_ is $(GROUP3) & ophi=1 & oplo=11; AtWRjw & s03=8; wrj47_ & s03_=0 { AtWRjw = wrj47_; }
# MOV @DRk,WRj
:MOV AtDRkw,wrj47_ is $(GROUP3) & ophi=1 & oplo=11; $(ATDRK) & AtDRkw & s03=10; wrj47_ & s03_=0 { AtDRkw = wrj47_; }
# MOV Rm,@WRj+dis16
:MOV rm47,AtWRj03Dis16b is $(GROUP3) & ophi=0 & oplo=9; rm47 ... & AtWRj03Dis16b { AtWRj03Dis16b = rm47; }
# MOV WRj,@WRj+dis16
:MOV wrj47,AtWRj03Dis16w is $(GROUP3) & ophi=4 & oplo=9; wrj47 ... & AtWRj03Dis16w { AtWRj03Dis16w = wrj47; }
# MOV Rm,@DRk+dis24
:MOV rm47,AtDRk03Dis24b is $(GROUP3) & ophi=2 & oplo=9; (rm47 & $(DRK03)) ... & AtDRk03Dis24b { AtDRk03Dis24b = rm47; }
# MOV WRj,@DRk+dis24
:MOV wrj47,AtDRk03Dis24w is $(GROUP3) & ophi=6 & oplo=9; (wrj47 & $(DRK03)) ... & AtDRk03Dis24w { AtDRk03Dis24w = wrj47; }
# MOV @WRj+dis16,Rm
:MOV AtWRj47Dis16b,rm03 is $(GROUP3) & ophi=1 & oplo=9; rm03 ... & AtWRj47Dis16b { AtWRj47Dis16b = rm03; }
# MOV @WRj+dis16,WRj
:MOV AtWRj47Dis16w,wrj03 is $(GROUP3) & ophi=5 & oplo=9; wrj03 ... & AtWRj47Dis16w { AtWRj47Dis16w = wrj03; }
# MOV @DRk+dis24,Rm
:MOV AtDRk47Dis24b,rm03 is $(GROUP3) & ophi=3 & oplo=9; (rm03 & $(DRK47)) ... & AtDRk47Dis24b { AtDRk47Dis24b = rm03; }
# MOV @DRk+dis24,WRj
:MOV AtDRk47Dis24w,wrj03 is $(GROUP3) & ophi=7 & oplo=9; (wrj03 & $(DRK47)) ... & AtDRk47Dis24w { AtDRk47Dis24w = wrj03; }
# MOV bit,C
:MOV xBitAddr,"CY" is $(GROUP3) & ophi=10 & oplo=9; (d47=9 & s3=0 & bit02; xBitByteAddr) & xBitAddr { xBitByteAddr = (xBitByteAddr) | (1<<bit02); }
# MOV C,bit
:MOV "CY",xBitAddr is $(GROUP3) & ophi=10 & oplo=9; (d47=10 & s3=0 & bit02; xBitByteAddr) & xBitAddr { $(CY)= ((xBitByteAddr>>bit02)&1); }
# MOVH DRk,#data16
:MOVH drk47,Data16x0 is $(GROUP3) & ophi=7 & oplo=14; $(DRK47) & s03=12; Data16x0 { drk47 = (drk47 & 0xffff0000) | (Data16x0 << 16); }
# MOVS WRj,Rm
:MOVZ wrj47,rm03 is $(GROUP3) & ophi=1 & oplo=10; wrj47 & rm03 { wrj47 = sext(rm03); }
# MOVZ WRj,Rm
:MOVZ wrj47,rm03 is $(GROUP3) & ophi=0 & oplo=10; wrj47 & rm03 { wrj47 = zext(rm03); }
# MUL Rmd,Rms
:MUL rm47,rm03 is $(GROUP3) & ophi=10 & oplo=12; rm47 & rm03 & rm47_d1 & rm47_d2 { result:2 = zext(rm47) * zext(rm03); tmp:2 = result>>8; rm47_d1 = tmp:1; rm47_d2 = result:1; }
# MUL WRjd,WRjs
:MUL wrj47,wrj03 is $(GROUP3) & ophi=10 & oplo=13; wrj47 & wrj03 & wrj47_d1 & wrj47_d2 { result:4 = zext(wrj47) * zext(wrj03); tmp:4 = result>>16; wrj47_d1 = tmp:2; wrj47_d2 = result:2; }
# ORL Rmd,Rms
:ORL rm47,rm03 is $(GROUP3) & ophi=4 & oplo=12; rm47 & rm03 { rm47 = rm47 | rm03; resultflags(rm47); }
# ORL WRjd,WRjs
:ORL wrj47,wrj03 is $(GROUP3) & ophi=4 & oplo=13; wrj47 & wrj03 { wrj47 = wrj47 | wrj03; resultflags(wrj47); }
# ORL Rm,#data
:ORL rm47,Data is $(GROUP3) & ophi=4 & oplo=14; rm47 & s03=0; Data { rm47 = rm47 | Data; resultflags(rm47); }
# ORL WRj,#data16
:ORL wrj47,Data16 is $(GROUP3) & ophi=4 & oplo=14; wrj47 & s03=4; Data16 { wrj47 = wrj47 | Data16; resultflags(wrj47); }
# ORL Rm,dir8
:ORL rm47,Direct is $(GROUP3) & ophi=4 & oplo=14; rm47 & s03=1; Direct { rm47 = rm47 | Direct; resultflags(rm47); }
# ORL WRj,dir8
:ORL wrj47,Direct8w is $(GROUP3) & ophi=4 & oplo=15; wrj47 & s03=5; Direct8w { wrj47 = wrj47 | Direct8w; resultflags(wrj47); }
# ORL Rm,dir16
:ORL rm47,Direct16b is $(GROUP3) & ophi=4 & oplo=14; rm47 & s03=3; Direct16b { rm47 = rm47 | Direct16b; resultflags(rm47); }
# ORL WRj,dir16
:ORL wrj47,Direct16w is $(GROUP3) & ophi=4 & oplo=14; wrj47 & s03=7; Direct16w { wrj47 = wrj47 | Direct16w; resultflags(wrj47); }
# ORL Rm,@WRj
:ORL rm47_,AtWRjb is $(GROUP3) & ophi=4 & oplo=14; AtWRjb & s03=9; rm47_ & s03_=0 { rm47_ = rm47_ | AtWRjb; resultflags(rm47_); }
# ORL Rm,@DRk
:ORL rm47_,AtDRkb is $(GROUP3) & ophi=4 & oplo=14; $(ATDRK) & AtDRkb & s03=11; rm47_ & s03_=0 { rm47_ = rm47_ | AtDRkb; resultflags(rm47_); }
# ORL C,bit
:ORL "CY",xBitAddr is $(GROUP3) & ophi=10 & oplo=9; (d47=7 & s3=0 & bit02; xBitByteAddr) & xBitAddr { $(CY) = ((xBitByteAddr>>bit02)&1) | $(CY); }
# ORL bit,C
:ORL "CY",xBitAddr2 is $(GROUP3) & ophi=10 & oplo=9; (d47=14 & s3=0 & bit02; xBitByteAddr) & xBitAddr2 { $(CY) = ((xBitByteAddr>>bit02)&1) | ($(CY) == 0); }
# POP Rm
:POP rm47 is $(GROUP3) & ophi=13 & oplo=10; rm47 & s03=8 { pop8(rm47); }
# POP WRj
:POP wrj47 is $(GROUP3) & ophi=13 & oplo=10; wrj47 & s03=9 { pop16(wrj47); }
# POP DRk
:POP drk47 is $(GROUP3) & ophi=13 & oplo=10; $(DRK47) & s03=11 { pop16(drk47); }
# PUSH #data
# TODO: manual did not specify A5 prefix, but would otherwise conflict with the XCH A,Rn instruction (8051)
:PUSH Data is $(GROUP3) & ophi=12 & oplo=10; d47=0 & s03=2; Data { push8(Data); }
# PUSH #data16
:PUSH Data16 is $(GROUP3) & ophi=12 & oplo=10; d47=0 & s03=6; Data16 { push16(Data16); }
# PUSH Rm
:PUSH rm47 is $(GROUP3) & ophi=12 & oplo=10; rm47 & s03=8 { push8(rm47); }
# PUSH WRj
:PUSH wrj47 is $(GROUP3) & ophi=12 & oplo=10; wrj47 & s03=9 { push16(wrj47); }
# PUSH DRk
:PUSH drk47 is $(GROUP3) & ophi=12 & oplo=10; $(DRK47) & s03=11 { push16(drk47); }
# SETB bit
:SETB xBitAddr^"."^xBitByteAddr is $(GROUP3) & ophi=10 & oplo=9; (d47=13 & s3=0 & bit02; xBitByteAddr) & xBitAddr { xBitByteAddr = (xBitByteAddr) | (1 << bit02); }
# SLL Rm
:SLL rm47 is $(GROUP3) & ophi=3 & oplo=14; rm47 & s03=0 { $(CY) = ((rm47>>7) & 1); rm47 = rm47 << 1; resultflags(rm47); }
# SLL WRj
:SLL wrj47 is $(GROUP3) & ophi=3 & oplo=14; wrj47 & s03=4 { $(CY) = ((wrj47>>15) & 1) == 1; wrj47 = wrj47 << 1; resultflags(wrj47); }
# SRA Rm
:SRA rm47 is $(GROUP3) & ophi=0 & oplo=14; rm47 & s03=0 { $(CY) = rm47 & 1; rm47 = rm47 s>> 1; resultflags(rm47); }
# SRA WRj
:SRA wrj47 is $(GROUP3) & ophi=0 & oplo=14; wrj47 & s03=4 { $(CY) = (wrj47 & 1) == 1; wrj47 = wrj47 s>> 1; resultflags(wrj47); }
# SRL Rm
:SRL rm47 is $(GROUP3) & ophi=1 & oplo=14; rm47 & s03=0 { $(CY) = rm47 & 1; rm47 = rm47 >> 1; resultflags(rm47); }
# SRL WRj
:SRL wrj47 is $(GROUP3) & ophi=1 & oplo=14; wrj47 & s03=4 { $(CY) = (wrj47 & 1) == 1; wrj47 = wrj47 >> 1; resultflags(wrj47); }
# SUB Rmd,Rms
:SUB rm47,rm03 is $(GROUP3) & ophi=9 & oplo=12; rm47 & rm03 { subflags(rm47,rm03); rm47 = rm47 - rm03; resultflags(rm47); }
# SUB WRjd,WRjs
:SUB wrj47,wrj03 is $(GROUP3) & ophi=9 & oplo=13; wrj47 & wrj03 { subflags(wrj47,wrj03); wrj47 = wrj47 - wrj03; resultflags(wrj47); }
# SUB DRkd,DRks
:SUB drk47,drk03 is $(GROUP3) & ophi=9 & oplo=15; $(DRK47) & $(DRK03) { subflags(drk47,drk03); drk47 = drk47 - drk03; resultflags(drk47);}
# SUB Rm,#data
:SUB rm47,Data is $(GROUP3) & ophi=9 & oplo=14; rm47 & s03=0; Data { subflags(rm47,Data); rm47 = rm47 - Data; resultflags(rm47);}
# SUB WRj,#data16
:SUB wrj47,Data16 is $(GROUP3) & ophi=9 & oplo=14; wrj47 & s03=4; Data16 { subflags(wrj47,Data16); wrj47 = wrj47 - Data16; resultflags(wrj47);}
# SUB DRk,#data16
:SUB drk47,Data16x0 is $(GROUP3) & ophi=9 & oplo=14; $(DRK47) & s03=8; Data16x0 { subflags(drk47,Data16x0); drk47 = drk47 - Data16x0; resultflags(drk47);}
# SUB Rm,dir8
:SUB rm47,Direct is $(GROUP3) & ophi=9 & oplo=14; rm47 & s03=1; Direct { subflags(rm47,Direct); rm47 = rm47 - Direct; resultflags(rm47);}
# SUB WRj,dir8
:SUB wrj47,Direct8w is $(GROUP3) & ophi=9 & oplo=14; wrj47 & s03=5; Direct8w { subflags(wrj47,Direct8w); wrj47 = wrj47 - Direct8w; resultflags(wrj47);}
# SUB Rm,dir16
:SUB rm47,Direct16b is $(GROUP3) & ophi=9 & oplo=14; rm47 & s03=3; Direct16b { subflags(rm47,Direct16b); rm47 = rm47 - Direct16b; resultflags(rm47);}
# SUB WRj,dir16
:SUB wrj47,Direct16w is $(GROUP3) & ophi=9 & oplo=14; wrj47 & s03=7; Direct16w { subflags(wrj47,Direct16w); wrj47 = wrj47 - Direct16w; resultflags(wrj47);}
# SUB Rm,@WRj
:SUB rm47_,AtWRjb is $(GROUP3) & ophi=9 & oplo=14; AtWRjb & s03=9; rm47_ & s03_=0 { subflags(rm47_,AtWRjb); rm47_ = rm47_ - AtWRjb; resultflags(rm47_);}
# SUB Rm,@DRk
:SUB rm47_,AtDRkb is $(GROUP3) & ophi=9 & oplo=14; $(ATDRK) & AtDRkb & s03=11; rm47_ & s03_=0 { subflags(rm47_,AtDRkb); rm47_ = rm47_ - AtDRkb; resultflags(rm47_);}
# XRL Rmd,Rms
:XRL rm47,rm03 is $(GROUP3) & ophi=6 & oplo=12; rm47 & rm03 { rm47 = rm47 ^ rm03; resultflags(rm47); }
# XRL WRjd,WRjs
:XRL wrj47,wrj03 is $(GROUP3) & ophi=6 & oplo=13; wrj47 & wrj03 { wrj47 = wrj47 ^ wrj03; resultflags(wrj47); }
# XRL Rm,#data
:XRL rm47,Data is $(GROUP3) & ophi=6 & oplo=14; rm47 & s03=0; Data { rm47 = rm47 ^ Data; resultflags(rm47); }
# XRL WRj,#data16
:XRL wrj47,Data16 is $(GROUP3) & ophi=6 & oplo=14; wrj47 & s03=4; Data16 { wrj47 = wrj47 ^ Data16; resultflags(wrj47); }
# XRL Rm,dir8
:XRL rm47,Direct is $(GROUP3) & ophi=6 & oplo=14; rm47 & s03=1; Direct { rm47 = rm47 ^ Direct; resultflags(rm47); }
# XRL WRj,dir8
:XRL wrj47,Direct8w is $(GROUP3) & ophi=6 & oplo=14; wrj47 & s03=5; Direct8w { wrj47 = wrj47 ^ Direct8w; resultflags(wrj47); }
# XRL Rm,dir16
:XRL rm47,Direct16b is $(GROUP3) & ophi=6 & oplo=14; rm47 & s03=3; Direct16b { rm47 = rm47 ^ Direct16b; resultflags(rm47); }
# XRL WRj,dir16
:XRL wrj47,Direct16w is $(GROUP3) & ophi=6 & oplo=14; wrj47 & s03=7; Direct16w { wrj47 = wrj47 ^ Direct16w; resultflags(wrj47); }
# XRL Rm,@Wrj
:XRL rm47_,AtWRjb is $(GROUP3) & ophi=6 & oplo=14; AtWRjb & s03=9; rm47_ & s03_=0 { rm47_ = rm47_ ^ AtWRjb; resultflags(rm47_); }
# XRL Rm,@Drk
:XRL rm47_,AtDRkb is $(GROUP3) & ophi=6 & oplo=14; $(ATDRK) & AtDRkb & s03=11; rm47_ & s03_=0 { rm47_ = rm47_ ^ AtDRkb; resultflags(rm47_); }
@@ -0,0 +1,5 @@
@define MCS251 ""
@include "8051_main.sinc"
@include "80251.sinc"
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<compiler_spec>
<global>
<range space="CODE"/>
<range space="INTMEM"/>
<range space="SFR"/>
<range space="EXTMEM"/>
<range space="BITS"/>
</global>
<stackpointer register="SP" space="INTMEM" growth="positive"/>
<default_proto>
<prototype name="__stdcall" extrapop="-3" stackshift="-3" strategy="register">
<input>
<pentry minsize="1" maxsize="1">
<register name="ACC"/>
</pentry>
<pentry minsize="1" maxsize="3">
<register name="DPTR"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="B"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="R0"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="R1"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="R2"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="R3"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="R4"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="R5"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="R6"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="R7"/>
</pentry>
</input>
<output>
<pentry minsize="1" maxsize="1">
<register name="ACC"/>
</pentry>
</output>
<unaffected>
<register name="SP"/>
</unaffected>
<localrange>
<range space="stack" first="0x0" last="0xf"/>
</localrange>
</prototype>
</default_proto>
</compiler_spec>
@@ -0,0 +1,3 @@
@define MCS80390 ""
@include "8051_main.sinc"
@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="UTF-8"?>
<compiler_spec>
<global>
<range space="CODE"/>
<range space="INTMEM"/>
<range space="SFR"/>
<range space="EXTMEM"/>
<range space="BITS"/>
</global>
<stackpointer register="SP" space="INTMEM" growth="positive"/>
<default_proto>
<prototype name="__stdcall" extrapop="-2" stackshift="-2" strategy="register">
<input>
<pentry minsize="1" maxsize="1">
<register name="ACC"/>
</pentry>
<pentry minsize="1" maxsize="2">
<register name="DPTR"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="B"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="R0"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="R1"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="R2"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="R3"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="R4"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="R5"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="R6"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="R7"/>
</pentry>
</input>
<output>
<pentry minsize="1" maxsize="1">
<register name="ACC"/>
</pentry>
</output>
<unaffected>
<register name="SP"/>
</unaffected>
<localrange>
<range space="stack" first="0x0" last="0xf"/>
</localrange>
</prototype>
</default_proto>
<callfixup name="switch_override_ACC">
<pcode>
<body><![CDATA[
PC = inst_next + zext(ACC) * 3;
goto [PC];
]]></body>
</pcode>
</callfixup>
</compiler_spec>
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<language_definitions>
<language processor="8051"
endian="big"
size="16"
variant="default"
version="2.0"
slafile="8051.sla"
processorspec="8051.pspec"
manualindexfile="../manuals/8051.idx"
id="8051:BE:16:default">
<description>8051 Microcontroller Family</description>
<compiler name="default" spec="8051.cspec" id="default"/>
<compiler name="Archimedes" spec="8051_archimedes.cspec" id="Archimedes"/>
<external_name tool="IDA-PRO" name="8051"/>
</language>
<language processor="80251"
endian="big"
size="16"
variant="default"
version="2.0"
slafile="80251.sla"
processorspec="80251.pspec"
id="80251:BE:24:default">
<description>80251 Microcontroller Family</description>
<compiler name="default" spec="80251.cspec" id="default"/>
</language>
<language processor="80390"
endian="big"
size="16"
variant="default"
version="1.0"
slafile="80390.sla"
processorspec="8051.pspec"
id="80390:BE:24:default">
<description>80390 in flat mode</description>
<compiler name="default" spec="80390.cspec" id="default"/>
</language>
<language processor="8051"
endian="big"
size="16"
variant="mx51"
version="2.0"
slafile="mx51.sla"
processorspec="mx51.pspec"
manualindexfile="../manuals/8051.idx"
id="8051:BE:24:mx51">
<description>NXP/Phillips MX51</description>
<compiler name="default" spec="mx51.cspec" id="default"/>
<external_name tool="IDA-PRO" name="8051"/>
</language>
</language_definitions>
@@ -0,0 +1,413 @@
<?xml version="1.0" encoding="UTF-8"?>
<processor_spec>
<programcounter register="PC"/>
<volatile outputop="write_volatile" inputop="read_volatile">
<range space="SFR" first="0x0" last="0xFF"/>
<range space="BITS" first="0x80" last="0xFF"/>
</volatile>
<default_symbols>
<symbol name="BANK0_R0" address="INTMEM:00"/>
<symbol name="BANK0_R1" address="INTMEM:01"/>
<symbol name="BANK0_R2" address="INTMEM:02"/>
<symbol name="BANK0_R3" address="INTMEM:03"/>
<symbol name="BANK0_R4" address="INTMEM:04"/>
<symbol name="BANK0_R5" address="INTMEM:05"/>
<symbol name="BANK0_R6" address="INTMEM:06"/>
<symbol name="BANK0_R7" address="INTMEM:07"/>
<symbol name="BANK1_R0" address="INTMEM:08"/>
<symbol name="BANK1_R1" address="INTMEM:09"/>
<symbol name="BANK1_R2" address="INTMEM:0a"/>
<symbol name="BANK1_R3" address="INTMEM:0b"/>
<symbol name="BANK1_R4" address="INTMEM:0c"/>
<symbol name="BANK1_R5" address="INTMEM:0d"/>
<symbol name="BANK1_R6" address="INTMEM:0e"/>
<symbol name="BANK1_R7" address="INTMEM:0f"/>
<symbol name="BANK2_R0" address="INTMEM:10"/>
<symbol name="BANK2_R1" address="INTMEM:11"/>
<symbol name="BANK2_R2" address="INTMEM:12"/>
<symbol name="BANK2_R3" address="INTMEM:13"/>
<symbol name="BANK2_R4" address="INTMEM:14"/>
<symbol name="BANK2_R5" address="INTMEM:15"/>
<symbol name="BANK2_R6" address="INTMEM:16"/>
<symbol name="BANK2_R7" address="INTMEM:17"/>
<symbol name="BANK3_R0" address="INTMEM:18"/>
<symbol name="BANK3_R1" address="INTMEM:19"/>
<symbol name="BANK3_R2" address="INTMEM:1a"/>
<symbol name="BANK3_R3" address="INTMEM:1b"/>
<symbol name="BANK3_R4" address="INTMEM:1c"/>
<symbol name="BANK3_R5" address="INTMEM:1d"/>
<symbol name="BANK3_R6" address="INTMEM:1e"/>
<symbol name="BANK3_R7" address="INTMEM:1f"/>
<symbol name="P0" address="SFR:80"/>
<symbol name="SP" address="SFR:81"/>
<symbol name="DPL" address="SFR:82"/>
<symbol name="DPH" address="SFR:83"/>
<symbol name="DPXL" address="SFR:84"/>
<symbol name="PCON" address="SFR:87"/>
<symbol name="TCON" address="SFR:88"/>
<symbol name="TMOD" address="SFR:89"/>
<symbol name="TL0" address="SFR:8a"/>
<symbol name="TL1" address="SFR:8b"/>
<symbol name="TH0" address="SFR:8c"/>
<symbol name="TH1" address="SFR:8d"/>
<symbol name="FADDR" address="SFR:8f"/>
<symbol name="P1" address="SFR:90"/>
<symbol name="DPX" address="SFR:93"/>
<symbol name="HADDR" address="SFR:97"/>
<symbol name="SCON" address="SFR:98"/>
<symbol name="SBUF" address="SFR:99"/>
<symbol name="P2" address="SFR:a0"/>
<symbol name="HIE" address="SFR:a1"/>
<symbol name="FIE" address="SFR:a2"/>
<symbol name="FIE1" address="SFR:a3"/>
<symbol name="WDTRST" address="SFR:a6"/>
<symbol name="WCON" address="SFR:a7"/>
<symbol name="IE" address="SFR:a8"/>
<symbol name="SADDR" address="SFR:a9"/>
<symbol name="HSTAT" address="SFR:ae"/>
<symbol name="P3" address="SFR:b0"/>
<symbol name="IEN1" address="SFR:b1"/>
<symbol name="IPL1" address="SFR:b2"/>
<symbol name="IPH1" address="SFR:b3"/>
<symbol name="IPH0" address="SFR:b7"/>
<symbol name="IP" address="SFR:b8"/>
<symbol name="SADEN" address="SFR:b9"/>
<symbol name="SPH" address="SFR:be"/>
<symbol name="FIFLG" address="SFR:c0"/>
<symbol name="FIFLG1" address="SFR:c1"/>
<symbol name="EPCONFIG" address="SFR:c7"/>
<symbol name="T2CON" address="SFR:c8"/>
<symbol name="T2MOD" address="SFR:c9"/>
<symbol name="RCAP2L" address="SFR:ca"/>
<symbol name="RCAP2H" address="SFR:cb"/>
<symbol name="TL2" address="SFR:cc"/>
<symbol name="TH2" address="SFR:cd"/>
<symbol name="HPCON" address="SFR:cf"/>
<symbol name="PSW" address="SFR:d0"/>
<symbol name="PSW1" address="SFR:d1"/>
<symbol name="SOFL" address="SFR:d2"/>
<symbol name="HPINDEX" address="SFR:d4"/>
<symbol name="HPSC" address="SFR:d5"/>
<symbol name="HPSTAT" address="SFR:d7"/>
<symbol name="CCON" address="SFR:d8"/>
<symbol name="CMOD" address="SFR:d9"/>
<symbol name="CCAPM0" address="SFR:da"/>
<symbol name="CCAPM1" address="SFR:db"/>
<symbol name="CCAPM2" address="SFR:dc"/>
<symbol name="CCAPM3" address="SFR:dd"/>
<symbol name="CCAPM4" address="SFR:de"/>
<symbol name="PCON1" address="SFR:df"/>
<symbol name="ACC" address="SFR:e0"/>
<symbol name="EPCON" address="SFR:e1"/>
<symbol name="RXSTAT" address="SFR:e2"/>
<symbol name="RXDAT" address="SFR:e3"/>
<symbol name="RXCON" address="SFR:e4"/>
<symbol name="RXFLG" address="SFR:e5"/>
<symbol name="RXCNTL" address="SFR:e6"/>
<symbol name="RXCNTH" address="SFR:e7"/>
<symbol name="HIFLG" address="SFR:e8"/>
<symbol name="CL" address="SFR:e9"/>
<symbol name="CCAP0L" address="SFR:ea"/>
<symbol name="CCAP1L" address="SFR:eb"/>
<symbol name="CCAP2L" address="SFR:ec"/>
<symbol name="CCAP3L" address="SFR:ed"/>
<symbol name="CCAP4L" address="SFR:ee"/>
<symbol name="B" address="SFR:f0"/>
<symbol name="EPINDEX" address="SFR:f1"/>
<symbol name="TXSTAT" address="SFR:f2"/>
<symbol name="TXDAT" address="SFR:f3"/>
<symbol name="TXCON" address="SFR:f4"/>
<symbol name="TXFLG" address="SFR:f5"/>
<symbol name="TXCNTL" address="SFR:f6"/>
<symbol name="TXCNTH" address="SFR:f7"/>
<symbol name="CH" address="SFR:f9"/>
<symbol name="CCAP0H" address="SFR:fa"/>
<symbol name="CCAP1H" address="SFR:fb"/>
<symbol name="CCAP2H" address="SFR:fc"/>
<symbol name="CCAP3H" address="SFR:fd"/>
<symbol name="CCAP4H" address="SFR:fe"/>
<symbol name="20.0" address="BITS:00"/>
<symbol name="20.1" address="BITS:01"/>
<symbol name="20.2" address="BITS:02"/>
<symbol name="20.3" address="BITS:03"/>
<symbol name="20.4" address="BITS:04"/>
<symbol name="20.5" address="BITS:05"/>
<symbol name="20.6" address="BITS:06"/>
<symbol name="20.7" address="BITS:07"/>
<symbol name="21.0" address="BITS:08"/>
<symbol name="21.1" address="BITS:09"/>
<symbol name="21.2" address="BITS:0a"/>
<symbol name="21.3" address="BITS:0b"/>
<symbol name="21.4" address="BITS:0c"/>
<symbol name="21.5" address="BITS:0d"/>
<symbol name="21.6" address="BITS:0e"/>
<symbol name="21.7" address="BITS:0f"/>
<symbol name="22.0" address="BITS:10"/>
<symbol name="22.1" address="BITS:11"/>
<symbol name="22.2" address="BITS:12"/>
<symbol name="22.3" address="BITS:13"/>
<symbol name="22.4" address="BITS:14"/>
<symbol name="22.5" address="BITS:15"/>
<symbol name="22.6" address="BITS:16"/>
<symbol name="22.7" address="BITS:17"/>
<symbol name="23.0" address="BITS:18"/>
<symbol name="23.1" address="BITS:19"/>
<symbol name="23.2" address="BITS:1a"/>
<symbol name="23.3" address="BITS:1b"/>
<symbol name="23.4" address="BITS:1c"/>
<symbol name="23.5" address="BITS:1d"/>
<symbol name="23.6" address="BITS:1e"/>
<symbol name="23.7" address="BITS:1f"/>
<symbol name="24.0" address="BITS:20"/>
<symbol name="24.1" address="BITS:21"/>
<symbol name="24.2" address="BITS:22"/>
<symbol name="24.3" address="BITS:23"/>
<symbol name="24.4" address="BITS:24"/>
<symbol name="24.5" address="BITS:25"/>
<symbol name="24.6" address="BITS:26"/>
<symbol name="24.7" address="BITS:27"/>
<symbol name="25.0" address="BITS:28"/>
<symbol name="25.1" address="BITS:29"/>
<symbol name="25.2" address="BITS:2a"/>
<symbol name="25.3" address="BITS:2b"/>
<symbol name="25.4" address="BITS:2c"/>
<symbol name="25.5" address="BITS:2d"/>
<symbol name="25.6" address="BITS:2e"/>
<symbol name="25.7" address="BITS:2f"/>
<symbol name="26.0" address="BITS:30"/>
<symbol name="26.1" address="BITS:31"/>
<symbol name="26.2" address="BITS:32"/>
<symbol name="26.3" address="BITS:33"/>
<symbol name="26.4" address="BITS:34"/>
<symbol name="26.5" address="BITS:35"/>
<symbol name="26.6" address="BITS:36"/>
<symbol name="26.7" address="BITS:37"/>
<symbol name="27.0" address="BITS:38"/>
<symbol name="27.1" address="BITS:39"/>
<symbol name="27.2" address="BITS:3a"/>
<symbol name="27.3" address="BITS:3b"/>
<symbol name="27.4" address="BITS:3c"/>
<symbol name="27.5" address="BITS:3d"/>
<symbol name="27.6" address="BITS:3e"/>
<symbol name="27.7" address="BITS:3f"/>
<symbol name="28.0" address="BITS:40"/>
<symbol name="28.1" address="BITS:41"/>
<symbol name="28.2" address="BITS:42"/>
<symbol name="28.3" address="BITS:43"/>
<symbol name="28.4" address="BITS:44"/>
<symbol name="28.5" address="BITS:45"/>
<symbol name="28.6" address="BITS:46"/>
<symbol name="28.7" address="BITS:47"/>
<symbol name="29.0" address="BITS:48"/>
<symbol name="29.1" address="BITS:49"/>
<symbol name="29.2" address="BITS:4a"/>
<symbol name="29.3" address="BITS:4b"/>
<symbol name="29.4" address="BITS:4c"/>
<symbol name="29.5" address="BITS:4d"/>
<symbol name="29.6" address="BITS:4e"/>
<symbol name="29.7" address="BITS:4f"/>
<symbol name="2a.0" address="BITS:50"/>
<symbol name="2a.1" address="BITS:51"/>
<symbol name="2a.2" address="BITS:52"/>
<symbol name="2a.3" address="BITS:53"/>
<symbol name="2a.4" address="BITS:54"/>
<symbol name="2a.5" address="BITS:55"/>
<symbol name="2a.6" address="BITS:56"/>
<symbol name="2a.7" address="BITS:57"/>
<symbol name="2b.0" address="BITS:58"/>
<symbol name="2b.1" address="BITS:59"/>
<symbol name="2b.2" address="BITS:5a"/>
<symbol name="2b.3" address="BITS:5b"/>
<symbol name="2b.4" address="BITS:5c"/>
<symbol name="2b.5" address="BITS:5d"/>
<symbol name="2b.6" address="BITS:5e"/>
<symbol name="2b.7" address="BITS:5f"/>
<symbol name="2c.0" address="BITS:60"/>
<symbol name="2c.1" address="BITS:61"/>
<symbol name="2c.2" address="BITS:62"/>
<symbol name="2c.3" address="BITS:63"/>
<symbol name="2c.4" address="BITS:64"/>
<symbol name="2c.5" address="BITS:65"/>
<symbol name="2c.6" address="BITS:66"/>
<symbol name="2c.7" address="BITS:67"/>
<symbol name="2d.0" address="BITS:68"/>
<symbol name="2d.1" address="BITS:69"/>
<symbol name="2d.2" address="BITS:6a"/>
<symbol name="2d.3" address="BITS:6b"/>
<symbol name="2d.4" address="BITS:6c"/>
<symbol name="2d.5" address="BITS:6d"/>
<symbol name="2d.6" address="BITS:6e"/>
<symbol name="2d.7" address="BITS:6f"/>
<symbol name="2e.0" address="BITS:70"/>
<symbol name="2e.1" address="BITS:71"/>
<symbol name="2e.2" address="BITS:72"/>
<symbol name="2e.3" address="BITS:73"/>
<symbol name="2e.4" address="BITS:74"/>
<symbol name="2e.5" address="BITS:75"/>
<symbol name="2e.6" address="BITS:76"/>
<symbol name="2e.7" address="BITS:77"/>
<symbol name="2f.0" address="BITS:78"/>
<symbol name="2f.1" address="BITS:79"/>
<symbol name="2f.2" address="BITS:7a"/>
<symbol name="2f.3" address="BITS:7b"/>
<symbol name="2f.4" address="BITS:7c"/>
<symbol name="2f.5" address="BITS:7d"/>
<symbol name="2f.6" address="BITS:7e"/>
<symbol name="2f.7" address="BITS:7f"/>
<symbol name="P0.0" address="BITS:80"/>
<symbol name="P0.1" address="BITS:81"/>
<symbol name="P0.2" address="BITS:82"/>
<symbol name="P0.3" address="BITS:83"/>
<symbol name="P0.4" address="BITS:84"/>
<symbol name="P0.5" address="BITS:85"/>
<symbol name="P0.6" address="BITS:86"/>
<symbol name="P0.7" address="BITS:87"/>
<symbol name="IT0" address="BITS:88"/>
<symbol name="IE0" address="BITS:89"/>
<symbol name="IT1" address="BITS:8a"/>
<symbol name="IE1" address="BITS:8b"/>
<symbol name="TR0" address="BITS:8c"/>
<symbol name="TF0" address="BITS:8d"/>
<symbol name="TR1" address="BITS:8e"/>
<symbol name="TF1" address="BITS:8f"/>
<symbol name="P1.0" address="BITS:90"/>
<symbol name="P1.1" address="BITS:91"/>
<symbol name="P1.2" address="BITS:92"/>
<symbol name="P1.3" address="BITS:93"/>
<symbol name="P1.4" address="BITS:94"/>
<symbol name="P1.5" address="BITS:95"/>
<symbol name="P1.6" address="BITS:96"/>
<symbol name="P1.7" address="BITS:97"/>
<symbol name="RI" address="BITS:98"/>
<symbol name="TI" address="BITS:99"/>
<symbol name="RB8" address="BITS:9a"/>
<symbol name="TB8" address="BITS:9b"/>
<symbol name="REN" address="BITS:9c"/>
<symbol name="SM2" address="BITS:9d"/>
<symbol name="SM1" address="BITS:9e"/>
<symbol name="SM0" address="BITS:9f"/>
<symbol name="P2.0" address="BITS:a0"/>
<symbol name="P2.1" address="BITS:a1"/>
<symbol name="P2.2" address="BITS:a2"/>
<symbol name="P2.3" address="BITS:a3"/>
<symbol name="P2.4" address="BITS:a4"/>
<symbol name="P2.5" address="BITS:a5"/>
<symbol name="P2.6" address="BITS:a6"/>
<symbol name="P2.7" address="BITS:a7"/>
<symbol name="EX0" address="BITS:a8"/>
<symbol name="ET0" address="BITS:a9"/>
<symbol name="EX1" address="BITS:aa"/>
<symbol name="ET1" address="BITS:ab"/>
<symbol name="ES" address="BITS:ac"/>
<symbol name="ET2" address="BITS:ad"/>
<symbol name="EC" address="BITS:ae"/>
<symbol name="EA" address="BITS:af"/>
<symbol name="RXD" address="BITS:b0"/>
<symbol name="TXD" address="BITS:b1"/>
<symbol name="INT0" address="BITS:b2"/>
<symbol name="INT1" address="BITS:b3"/>
<symbol name="T0" address="BITS:b4"/>
<symbol name="T1" address="BITS:b5"/>
<symbol name="WR" address="BITS:b6"/>
<symbol name="RD" address="BITS:b7"/>
<symbol name="PX0" address="BITS:b8"/>
<symbol name="PT0" address="BITS:b9"/>
<symbol name="PX1" address="BITS:ba"/>
<symbol name="PT1" address="BITS:bb"/>
<symbol name="PS" address="BITS:bc"/>
<symbol name="PT2" address="BITS:bd"/>
<symbol name="PC" address="BITS:be"/>
<symbol name="IP.7" address="BITS:bf"/>
<symbol name="FIFLG.0" address="BITS:c0"/>
<symbol name="FIFLG.1" address="BITS:c1"/>
<symbol name="FIFLG.2" address="BITS:c2"/>
<symbol name="FIFLG.3" address="BITS:c3"/>
<symbol name="FIFLG.4" address="BITS:c4"/>
<symbol name="FIFLG.5" address="BITS:c5"/>
<symbol name="FIFLG.6" address="BITS:c6"/>
<symbol name="FIFLG.7" address="BITS:c7"/>
<symbol name="CPRL2" address="BITS:c8"/>
<symbol name="CT2" address="BITS:c9"/>
<symbol name="TR2" address="BITS:ca"/>
<symbol name="EXEN2" address="BITS:cb"/>
<symbol name="TCLK" address="BITS:cc"/>
<symbol name="RCLK" address="BITS:cd"/>
<symbol name="EXF2" address="BITS:ce"/>
<symbol name="TF2" address="BITS:cf"/>
<symbol name="P" address="BITS:d0"/>
<symbol name="UD" address="BITS:d1"/>
<symbol name="OV" address="BITS:d2"/>
<symbol name="RS0" address="BITS:d3"/>
<symbol name="RS1" address="BITS:d4"/>
<symbol name="F0" address="BITS:d5"/>
<symbol name="AC" address="BITS:d6"/>
<symbol name="C" address="BITS:d7"/>
<symbol name="CCF.0" address="BITS:d8"/>
<symbol name="CCF.1" address="BITS:d9"/>
<symbol name="CCF.2" address="BITS:da"/>
<symbol name="CCF.3" address="BITS:db"/>
<symbol name="CCF.4" address="BITS:dc"/>
<symbol name="CCON.5" address="BITS:dd"/>
<symbol name="CR" address="BITS:de"/>
<symbol name="CF" address="BITS:df"/>
<symbol name="ACC.0" address="BITS:e0"/>
<symbol name="ACC.1" address="BITS:e1"/>
<symbol name="ACC.2" address="BITS:e2"/>
<symbol name="ACC.3" address="BITS:e3"/>
<symbol name="ACC.4" address="BITS:e4"/>
<symbol name="ACC.5" address="BITS:e5"/>
<symbol name="ACC.6" address="BITS:e6"/>
<symbol name="ACC.7" address="BITS:e7"/>
<symbol name="HIFLG.0" address="BITS:e8"/>
<symbol name="HIFLG.1" address="BITS:e9"/>
<symbol name="HIFLG.2" address="BITS:ea"/>
<symbol name="HIFLG.3" address="BITS:eb"/>
<symbol name="HIFLG.4" address="BITS:ec"/>
<symbol name="HIFLG.5" address="BITS:ed"/>
<symbol name="HIFLG.6" address="BITS:ee"/>
<symbol name="HIFLG.7" address="BITS:ef"/>
<symbol name="B.0" address="BITS:f0"/>
<symbol name="B.1" address="BITS:f1"/>
<symbol name="B.2" address="BITS:f2"/>
<symbol name="B.3" address="BITS:f3"/>
<symbol name="B.4" address="BITS:f4"/>
<symbol name="B.5" address="BITS:f5"/>
<symbol name="B.6" address="BITS:f6"/>
<symbol name="B.7" address="BITS:f7"/>
<symbol name="F8.0" address="BITS:f8"/>
<symbol name="F8.1" address="BITS:f9"/>
<symbol name="F8.2" address="BITS:fa"/>
<symbol name="F8.3" address="BITS:fb"/>
<symbol name="F8.4" address="BITS:fc"/>
<symbol name="F8.5" address="BITS:fd"/>
<symbol name="F8.6" address="BITS:fe"/>
<symbol name="F8.7" address="BITS:ff"/>
</default_symbols>
<default_memory_blocks>
<memory_block name="REG_BANK_1" start_address="INTMEM:0" length="0x8" initialized="false"/>
<memory_block name="REG_BANK_2" start_address="INTMEM:8" length="0x8" initialized="false"/>
<memory_block name="REG_BANK_3" start_address="INTMEM:10" length="0x8" initialized="false"/>
<memory_block name="REG_BANK_4" start_address="INTMEM:18" length="0x8" initialized="false"/>
<memory_block name="INTMEM" start_address="INTMEM:20" length="0xe0" initialized="false"/>
<memory_block name="BITS" start_address="BITS:00" bit_mapped_address="INTMEM:20" length="0x80"/>
<memory_block name="SFR" start_address="SFR:80" length="0x80" initialized="false"/>
<!-- BUG: SFR-BITS do not map properly since only every 8th SFR register is mapped (e.g., 0x80, 0x88, 0x90 ... 0xF0, 0xF8) -->
<memory_block name="SFR-BITS" start_address="BITS:80" bit_mapped_address="SFR:80" length="0x80"/>
</default_memory_blocks>
</processor_spec>
@@ -0,0 +1,3 @@
@define MCS51 ""
@include "8051_main.sinc"
@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<compiler_spec>
<global>
<range space="CODE"/>
<range space="INTMEM"/>
<range space="SFR"/>
<range space="EXTMEM"/>
<range space="BITS"/>
</global>
<stackpointer register="SP" space="INTMEM" growth="positive"/>
<default_proto>
<prototype name="ret_in_r7" extrapop="-2" stackshift="-2" strategy="register">
<input>
<pentry maxsize="1" minsize="1">
<register name="R1"/>
</pentry>
<pentry maxsize="1" minsize="1">
<register name="R2"/>
</pentry>
<pentry maxsize="1" minsize="1">
<register name="R3"/>
</pentry>
<pentry maxsize="1" minsize="1">
<register name="R4"/>
</pentry>
<pentry maxsize="1" minsize="1">
<register name="R5"/>
</pentry>
<pentry maxsize="1" minsize="1">
<register name="R6"/>
</pentry>
<pentry maxsize="1" minsize="1">
<register name="R7"/>
</pentry>
<pentry maxsize="1" minsize="1">
<register name="ACC"/>
</pentry>
</input>
<output>
<pentry maxsize="1" minsize="1">
<register name="R7"/>
</pentry>
</output>
<unaffected>
<register name="SP"/>
</unaffected>
<!-- This first range lists the permissible stack offsets
that can be used as scratch and/or local variables -->
<localrange>
<range space="stack" first="0x0" last="0xf"/>
</localrange>
</prototype>
</default_proto>
<prototype name="ret_in_a" extrapop="-2" stackshift="-2" strategy="register">
<input>
<pentry maxsize="1" minsize="1">
<register name="R1"/>
</pentry>
<pentry maxsize="1" minsize="1">
<register name="R2"/>
</pentry>
<pentry maxsize="1" minsize="1">
<register name="R3"/>
</pentry>
<pentry maxsize="1" minsize="1">
<register name="R4"/>
</pentry>
<pentry maxsize="1" minsize="1">
<register name="R5"/>
</pentry>
<pentry maxsize="1" minsize="1">
<register name="R6"/>
</pentry>
<pentry maxsize="1" minsize="1">
<register name="R7"/>
</pentry>
<pentry maxsize="1" minsize="1">
<register name="ACC"/>
</pentry>
</input>
<output>
<pentry maxsize="1" minsize="1">
<register name="ACC"/>
</pentry>
</output>
<unaffected>
<register name="SP"/>
</unaffected>
<!-- This first range lists the permissible stack offsets
that can be used as scratch and/or local variables -->
<localrange>
<range space="stack" first="0x0" last="0xf"/>
</localrange>
</prototype>
</compiler_spec>
@@ -0,0 +1,917 @@
# sleigh specification file for Intel 8051
#@define BIT_OPS "PCODEOPS"
#@define BIT_OPS "SHIFTS"
@define BIT_OPS "BIT_ADDRS"
# It's sometimes clearer for decompilation to omit the pushing and
# restoring of the return value for function calls.
#@define OMIT_RETADDR
# TODO !!! need to fully employ resultflags macro after resolving the use of the above BIT_OPS !!!
# TODO !!! Need to reconcile use of PSW vs. PSW1 for MCS251 !!!
# TODO !!! Need to fill-out SFR bits in 80251.pspec !!!
@if defined(ENDIAN)
define endian=$(ENDIAN);
@else
define endian=big;
@endif
define alignment=1;
@if defined(MCS251)
@define PTRSIZE 3
@define SP_SIZE 3
define space RAM type=ram_space size=3 default;
define space SFR type=ram_space size=2;
define space BITS type=ram_space size=2;
# 8051 spaces map to the following regions of the 80251 RAM space:
# CODE - 0xff0000-0xffffff
# EXTERNAL - 0x010000-0x01ffff
# INTERNAL - 0x000000-0x0000ff
@elif defined(MCS51)
@if defined(PTRSIZE)
@else
@define PTRSIZE 2
@endif
# SP stack pointer should be set to the size of the space it is used in, to avoid "issues"
# This is a minor inconsistency with the model and the actual processor in some cases
# If pristine SP sizing is required for rollover and such, the model should be changed
#
@define SP_SIZE 1
define space CODE type=ram_space size=$(PTRSIZE) default;
define space INTMEM type=ram_space size=1;
define space EXTMEM type=ram_space size=2;
define space SFR type=ram_space size=1;
define space BITS type=ram_space size=1;
@elif defined(MCS80390)
@define PTRSIZE 3
@define SP_SIZE 1
define space CODE type=ram_space size=3 default;
define space INTMEM type=ram_space size=1;
define space EXTMEM type=ram_space size=3;
define space SFR type=ram_space size=1;
define space BITS type=ram_space size=1;
@elif defined(MX51)
@define PTRSIZE 3
@define SP_SIZE 3
# The right thing for decompilation is to represent these
# as part of one uniform space, similar to the 80251.
# Remember to load code at 800000
#
# xdata 0 (EXTMEM)
# data 7f0000 (INTMEM)
# code 800000
define space RAM type=ram_space size=3 default;
define space SFR type=ram_space size=1;
define space ESFR type=ram_space size=1;
define space BITS type=ram_space size=1;
define space EBITS type=ram_space size=1;
# Unsure where stack really is, but probably don't want it on normal
# registers
#@define STACKBASE 0x7f0100
@define STACKBASE 0
@else
# "error Unknown processor"
@endif
define space register type=register_space size=1;
# Register File
define register offset=0x00 size=1 [ R0 R1 R2 R3 R4 R5 R6 R7 ];
# for future jump table fixup
define register offset=0x70 size=1 [ jumpTableGuard1 jumpTableGuard2 ];
@if defined(MCS251)
define register offset=0x08 size=1 [ R8 R9 B ACC R12 R13 R14 R15
R16 R17 R18 R19 R20 R21 R22 R23
R24 R25 R26 R27 R28 R29 R30 R31
];
define register offset=0x0 size=2 [ WR0 WR2 WR4 WR6 WR8 AB WR12 WR14
WR16 WR18 WR20 WR22 WR24 WR26 WR28 WR30
];
define register offset=0x0 size=4 [ DR0 DR4 DR8 DR12 DR16 DR20 DR24 DR28 ];
define register offset=0x38 size=1 [ R56 DPXL DPH DPL R60 R61 SPH ];
define register offset=0x3A size=2 [ DPTR ];
define register offset=0x38 size=4 [ DPX SPX ];
@elif defined(MCS51) || defined(MCS80390) || defined(MX51)
define register offset=0x00 size=4 [ R0R1R2R3 ];
define register offset=0x01 size=3 [ R1R2R3 ]; # Used as R3R2R1
define register offset=0x01 size=2 [ R2R1 ];
define register offset=0x00 size=2 [ R0R1 R2R3 R4R5 R6R7 ];
define register offset=0x04 size=4 [ R4R5R6R7 ];
define register offset=0x05 size=3 [ R5R6R7 ];
define register offset=0x0A size=1 [ B ACC ]; # relocated to facilitate AB 16-bit access
define register offset=0x0A size=2 [ AB ];
@if defined(MCS51) || defined(MX51)
define register offset=0x82 size=2 [ DPTR ];
define register offset=0x82 size=1 [ DPH DPL ]; # relocated to facilitate DPTR 16-bit access
@elif defined(MCS80390)
# Following existing example, relocated DPX, DPH, and DPL for DPTR
# access. Rework some direct moves to compensate. Not clear that all
# cases are covered, thus might be problematic hack in the long term.
define register offset=0x82 size=3 [ DPTR ];
define register offset=0x82 size=1 [ DPX DPH DPL ];
@endif
@else
# "error Unknown processor"
@endif
define register offset=0x40 size=$(SP_SIZE) [ SP ];
define register offset=0x44 size=$(PTRSIZE) [ PC ];
define register offset=0x48 size=1 [ PSW ];
@if defined(DUAL_DPTR)
# Dual DPTR
# Rather than model it as context, we're just going
# to special case the INC and DEC instructions
# to swap the register values
define register offset=0x4a size=2 [ DPTR2 ];
define register offset=$(DPS_REG_NUM) size=1 [ AUXR1 ]; # Bit 0 is DPS
@endif
@define CY "PSW[7,1]"
@define AC "PSW[6,1]"
@define N "PSW[5,1]"
@define RS1 "PSW[4,1]"
@define RS0 "PSW[3,1]"
@define OV "PSW[2,1]"
@define Z "PSW[1,1]"
@if defined(MX51)
# remap these into the normal register file for decompiler use.
# Really belong on ESFR @0xfc - 0xfe with order EPL EPM EPH
define register offset=0xc0 size=1 [ EPH EPM EPL ];
define register offset=0xc0 size=3 [ EPTR ];
@endif
@if defined(MCS251)
define register offset=0x50 size=4 contextReg;
define context contextReg
phase = (0,0)
srcMode = (1,1) # (reflects UCONFIG0.0) 1: source mode, 0: binary mode
A5Prefix = (2,2) # reflects presence of A5 prefix
;
# GROUP1 - MCS51 instructions in 0x00-0x5F range
@define GROUP1 "epsilon"
# GROUP2 - MCS51 instructions in 0x60-0xff range
@define GROUP2 "((srcMode=0 & A5Prefix=0) | (srcMode=1 & A5Prefix=1))"
# GROUP3 - MCS251 instructions in 0x60-0xff range
@define GROUP3 "((srcMode=0 & A5Prefix=1) | (srcMode=1 & A5Prefix=0))"
@elif defined(MCS51) || defined(MCS80390) || defined(MX51)
@define GROUP1 "epsilon"
@define GROUP2 "epsilon"
@define GROUP3 "epsilon"
@endif
define pcodeop decimal_adjust;
define pcodeop nop;
@if BIT_OPS == "PCODEOPS"
define pcodeop get;
define pcodeop set;
define pcodeop set_bit_value;
define pcodeop clr;
@endif
#TOKENS
define token opbyte (8)
opfull = (0,7)
oplo = (0,3)
ophi = (4,7)
rn = (0,2)
rnfill = (3,3)
ri = (0,0)
rifill = (1,3)
opaddr = (5,7)
addrfill = (4,4)
b_0000 = (0,0)
b_0001 = (0,1)
b_0002 = (0,2)
b_0005 = (0,5)
b_0101 = (1,1)
b_0107 = (1,7)
b_0207 = (2,7)
b_0307 = (3,7)
b_0607 = (6,7)
@if defined(MX51)
PRi_sel = (2,2)
PRi_revend = (2,2) # reverse endian
emov_delta = (0,1)
@endif
;
define token AddrByte (8)
direct = (0,7)
bank = (7,7)
sfr = (0,6)
sfr6 = (6,6)
sfrlo = (0,3)
mainreg = (0,6)
direct17 = (1,7)
;
define token AddrByte2 (8)
direct2 = (0,7)
bank2 = (7,7)
sfr2 = (0,6)
sfr26 = (6,6)
sfr2lo = (0,3)
mainreg2 = (0,6)
;
define token BitByte (8)
bitaddr8 = (0,7)
bitaddr27 = (2,7)
bitbank = (7,7)
sfrbyte = (3,7)
bitaddr57 = (5,7)
sfrbit6 = (6,6)
sfrbit3 = (3,3)
sfrbit = (0,2) dec
lowbyte = (3,6)
bitaddr0 = (0,0)
;
define token AddrTwo (16)
addr16 = (0,15)
;
@if defined(MCS80390)
# todo: deconflict with 80251 version
define token AddrThree (24)
addr24 = (0,23)
;
@endif
define token RelByte (8) rel8=(0,7) signed;
define token ImmedByte (8) data=(0,7);
define token ImmedTwo (16)
data16 = (0,15)
rel16 = (0,15) signed
;
@if defined(MCS80390)
define token ImmedThree (24)
data24 = (0,23)
;
@endif
@if defined(MCS80390)
define token aopword (24)
aoplo = (16,19)
aopaddr = (21,23)
aaddrfill = (20,20)
adata = (0,15)
;
@else
define token aopword (16)
aoplo = (8,11)
aopaddr = (13,15)
aaddrfill = (12,12)
adata = (0,7)
;
@endif
attach variables rn [ R0 R1 R2 R3 R4 R5 R6 R7 ];
attach variables ri [ R0 R1 ];
# flags macros
#macro addflags(op1, op2) { # Flags set by add instructions
# PSW = PSW & 0x7b;
# PSW = PSW | (carry(op1,op2)<<7) # Check for carry
# | (scarry(op1,op2)<<2); # Check for signed carry
#}
#macro subflags(op1, op2) { # Flags set by sub instructions
# PSW = PSW & 0x7b;
# PSW = PSW | ((op1<op2)<<7) # Check for borrow
# | (sborrow(op1,op2)<<2); # Check for signed borrow
#}
#macro compflags(op1, op2) { # Flags set by the compare instructions
# PSW = PSW & 0x7f;
# PSW = PSW | ((op1 < op2) << 7);
#}
macro addflags(op1, op2) { # Flags set by add instructions
$(CY) = (carry(op1,op2)); # Check for carry
#OV = (scarry(op1,op2)); # Check for signed carry
}
macro subflags(op1, op2) { # Flags set by sub instructions
$(CY) = (op1 < op2); # Check for carry
#OV = sborrow(op1,op2); # Check for signed carry
}
macro compflags(op1, op2) { # Flags set by the compare instructions
$(CY) = (op1 < op2); # Check for carry
}
macro resultflags(op1) { # Set N,Z flag for results
$(N) = op1 s< 0;
$(Z) = op1 == 0;
}
macro push8(val) {
@if defined(MCS251)
SPX = SPX + 1;
ptr:3 = SPX:3;
*[RAM]:1 ptr = val;
@elif defined(MCS51) || defined(MCS80390)
SP = SP + 1;
*[INTMEM]:1 SP = val;
@elif defined(MX51)
SP = SP + 1;
#tmp:3 = zext(SP) + $(STACKBASE);
tmp:3 = SP;
*[RAM]:1 tmp = val;
@else
val = val;
@endif
}
@ifdef OMIT_RETADDR
@ifdef MCS80390
macro push24(val) { val = val; }
@else
macro push16(val) { val = val; }
@endif
@else
# Want to model pushes
@ifndef MCS80390
macro push16(val) {
@if defined(MCS251)
al:1 = val:1;
ah:1 = val(1);
SPX = SPX + 1;
*[RAM]:1 SPX:3 = al;
SPX = SPX + 1;
*[RAM]:1 SPX:3 = ah;
@elif defined(MCS51)
al:1 = val:1;
ah:1 = val(1);
SP = SP + 1;
*[INTMEM]:1 SP = al;
SP = SP + 1;
*[INTMEM]:1 SP = ah;
@elif defined(MX51)
# dptr push
#ptr:1 = SP + 1;
#tmp:3 = zext(ptr) + $(STACKBASE);
al:1 = val:1;
ah:1 = val(1);
SP = SP + 1;
*[RAM]:1 SP = al;
SP = SP + 1;
*[RAM]:1 SP = ah;
@else
val = val;
@endif
}
@else
#@if defined(MCS80390)
macro push24(val) {
al:1 = val:1;
ah:1 = val(1);
ax:1 = val(2);
SP = SP + 1;
*[INTMEM]:1 SP = al;
SP = SP + 1;
*[INTMEM]:1 SP = ah;
SP = SP + 1;
*[INTMEM]:1 SP = ax;
}
@endif
@endif
macro pop8(val) {
@if defined(MCS251)
ptr:3 = SPX:3;
val = *[RAM]:1 ptr;
SPX = SPX - 1;
@elif defined(MCS51) || defined(MCS80390)
val = *[INTMEM]:1 SP;
SP = SP - 1;
@elif defined(MX51)
#ptr:3 = zext(SP) + $(STACKBASE);
ptr:3 = SP;
val = *[RAM]:1 ptr;
SP = SP - 1;
@else
val = val;
@endif
}
@if defined(MCS80390)
@ifdef OMIT_RETADDR
macro pop24(val) { val = val; }
@else
macro pop24(val) {
ptr:1 = SP - 2;
al : 1 = *[INTMEM]:1 ptr;
ah : 1 = *[INTMEM]:1 (ptr+1);
ax : 1 = *[INTMEM]:1 (ptr+2);
bl:3 = zext(al);
bh:3 = zext(ah) << 8;
bx:3 = zext(ax) << 16;
z : 3 = bl;
z = (z | bh);
z = (z | bx);
val = z;
SP = ptr - 1;
}
@endif
@else
@ifdef OMIT_RETADDR
macro pop16(val) { val = val; }
@else
macro pop16(val) {
@if defined(MCS251)
ah:1 = *:1 SPX:$(SP_SIZE);
SPX = SPX - 1;
al:1 = *:1 SPX:$(SP_SIZE);
SPX = SPX - 1;
val = (zext(ah) << 8) | zext(al);
@elif defined(MCS51)
ah:1 = *[INTMEM]:1 SP;
SP = SP - 1;
al:1 = *[INTMEM]:1 SP;
SP = SP - 1;
val = (zext(ah) << 8) | zext(al);
@elif defined(MX51)
ah:1 = *[RAM]:1 SP;
SP = SP - 1;
al:1 = *[RAM]:1 SP;
SP = SP - 1;
val = (zext(ah) << 8) | zext(al);
@else
val = val;
@endif
}
@endif
@endif
# Operand display only
CY: "CY" is epsilon { }
Areg: "A" is ophi { export ACC; }
ABreg: AB is ophi & AB { export AB; }
DPTRreg: DPTR is ophi & DPTR { export DPTR; }
@if defined(MCS251)
ADPTR: "@A+"^DPTR is ophi & DPTR { ptr:3 = 0xff0000 + zext(DPTR) + zext(ACC); export ptr; }
@elif defined(MCS51)
ADPTR: "@A+"^DPTR is ophi & DPTR { ptr:$(PTRSIZE) = zext(DPTR) + zext(ACC); export ptr; }
@elif defined(MCS80390)
ADPTR: "@A+"^DPTR is ophi & DPTR { ptr:3 = zext(DPTR) + zext(ACC); export ptr; }
@elif defined(MX51)
ADPTR: "@A+"^DPTR is ophi & DPTR { ptr:3 = 0x800000 + zext(DPTR) + zext(ACC); export ptr; }
@endif
APC: "@A+PC" is epsilon { tmp:$(PTRSIZE) = inst_next + zext(ACC); export tmp; }
@if defined(MCS251)
ATDPTR: "@"^DPTR is ophi & DPTR { ptr:3 = 0x010000 + zext(DPTR); export *:1 ptr; } # 8051 External data address mapped into RAM space
@elif defined(MCS51)
ATDPTR: "@"^DPTR is ophi & DPTR { ptr:2 = DPTR; export *[EXTMEM]:1 ptr; }
@elif defined(MCS80390)
ATDPTR: "@"^DPTR is ophi & DPTR { ptr:3 = zext(DPTR); export *[EXTMEM]:1 ptr; }
@elif defined(MX51)
ATDPTR: "@"^DPTR is ophi & DPTR { ptr:3 = zext(DPTR); export *[RAM]:1 ptr; }
@endif
@if defined(MCS251)
Ri: @ri is ri { ptr:3 = zext(ri); export *[RAM]:1 ptr; }
@elif defined(MX51)
Ri: @ri is ri { ptr:3 = zext(ri) + 0x7f0000; export *[RAM]:1 ptr; }
@elif defined(MCS51) || defined(MCS80390)
Ri: @ri is ri { export *[INTMEM]:1 ri; }
@endif
@if defined(MCS251)
RiX: @ri is ri { ptr:3 = 0x010000 + zext(ri); export *:1 ptr; } # 8051 8-bit External data address mapped into RAM space
@elif defined(MCS51)
RiX: @ri is ri { ptr:2 = zext(ri); export *[EXTMEM]:1 ptr; } # limited to 8-bit external data address (I/O state can be used to produce 16-bit addr)
@elif defined(MCS80390)
RiX: @ri is ri { ptr:3 = zext(ri); export *[EXTMEM]:1 ptr; } # tocheck
@elif defined(MX51)
RiX: @ri is ri { ptr:3 = zext(ri); export *[RAM]:1 ptr; }
@endif
Data: "#"data is data { export *[const]:1 data; }
Data16: "#"data16 is data16 { export *[const]:2 data16; }
@if defined(MCS80390)
Data24: "#"data24 is data24 { export *[const]:3 data24; }
@endif
@if defined(MCS251)
Direct: mainreg is bank=0 & mainreg { export *[RAM]:1 mainreg; }
@elif defined(MX51)
Direct: mainreg is bank=0 & mainreg { tmp:3 = mainreg + 0x7f0000; export *[RAM]:1 tmp; }
@elif defined(MCS51) || defined(MCS80390)
Direct: mainreg is bank=0 & mainreg { export *[INTMEM]:1 mainreg; }
@endif
Direct: direct is bank=1 & direct { export *[SFR]:1 direct; }
Direct: PSW is bank=1 & direct=0xD0 & PSW { export PSW; }
Direct: "A" is bank=1 & direct=0xE0 { export ACC; }
Direct: B is bank=1 & direct=0xF0 & B { export B; }
Direct: DPL is bank=1 & direct=0x82 & DPL { export DPL; }
Direct: DPH is bank=1 & direct=0x83 & DPH { export DPH; }
@if defined(MCS80390)
Direct: DPX is bank=1 & direct=0x93 & DPX { export DPX; }
@endif
@if defined(MCS251)
Direct: DPXL is bank=1 & direct=0x84 & DPXL { export DPXL; }
@endif
@if defined(MCS251)
Direct2: mainreg2 is bank2=0 & mainreg2 { export *[RAM]:1 mainreg2; }
@elif defined(MX51)
Direct2: mainreg2 is bank2=0 & mainreg2 { tmp:3 = mainreg2 + 0x7f0000; export *[RAM]:1 tmp; }
@elif defined(MCS51) || defined(MCS80390)
Direct2: mainreg2 is bank2=0 & mainreg2 { export *[INTMEM]:1 mainreg2; }
@endif
Direct2: direct2 is bank2=1 & direct2 { export *[SFR]:1 direct2; }
Direct2: PSW is bank2=1 & direct2=0xD0 & PSW { export PSW; }
Direct2: "A" is bank2=1 & direct2=0xE0 { export ACC; }
Direct2: B is bank2=1 & direct2=0xF0 & B { export B; }
Direct2: DPL is bank2=1 & direct2=0x82 & DPL { export DPL; }
Direct2: DPH is bank2=1 & direct2=0x83 & DPH { export DPH; }
@if defined(MCS80390)
Direct2: DPX is bank2=1 & direct2=0x93 & DPX { export DPX; }
@endif
@if defined(MCS251)
Direct2: DPXL is bank2=1 & direct2=0x84 & DPXL { export DPXL; }
@endif
@if defined(MCS251)
BitAddr: bitaddr is bitbank=1 & sfrbyte & sfrbit [ bitaddr =(sfrbyte << 6)+sfrbit; ] { export *[BITS]:1 bitaddr; }
BitAddr: bitaddr is bitbank=0 & lowbyte & sfrbit [ bitaddr =(lowbyte << 3)+sfrbit; ] { export *[BITS]:1 bitaddr; }
BitAddr2: "/"bitaddr is bitbank=1 & sfrbyte & sfrbit [ bitaddr =(sfrbyte << 6)+sfrbit; ] { export *[BITS]:1 bitaddr; }
BitAddr2: "/"bitaddr is bitbank=0 & lowbyte & sfrbit [ bitaddr =(lowbyte << 3)+sfrbit; ] { export *[BITS]:1 bitaddr; }
@elif defined(MCS51) || defined(MCS80390) || defined(MX51)
##
##TODO !!! 8051 SFRBITS bit overlay block is probably incorrect since there is not a 1:1 mapping to the SFR space
## While the BitAddr is only used for disassembly markup, and labels come from pspec, the underlying data will
## not map correctly. We could switch completely to the full SFR bit mapping as done above for the 80251.
## This would require a change in the BITS space size.
##
BitAddr: bitaddr is bitbank=1 & sfrbyte & sfrbit [ bitaddr =(sfrbyte << 3)+sfrbit; ] { export *[BITS]:1 bitaddr; }
BitAddr: bitaddr is bitbank=0 & lowbyte & sfrbit [ bitaddr =(lowbyte << 3)+sfrbit; ] { export *[BITS]:1 bitaddr; }
BitAddr2: "/"bitaddr is bitbank=1 & sfrbyte & sfrbit [ bitaddr =(sfrbyte << 3)+sfrbit; ] { export *[BITS]:1 bitaddr; }
BitAddr2: "/"bitaddr is bitbank=0 & lowbyte & sfrbit [ bitaddr =(lowbyte << 3)+sfrbit; ] { export *[BITS]:1 bitaddr; }
@endif
BitByteAddr: byteaddr is bitbank=1 & sfrbyte & sfrbit [ byteaddr =(sfrbyte << 3); ] { export *[SFR]:1 byteaddr; }
BitByteAddr: "A" is bitbank=1 & sfrbyte=0x1C & sfrbit { export ACC; }
BitByteAddr: B is bitbank=1 & sfrbyte=0x1E & sfrbit & B { export B; }
BitByteAddr: PSW is bitbank=1 & sfrbyte=0x1A & sfrbit & PSW { export PSW; }
@if defined(MCS251)
BitByteAddr: byteaddr is bitbank=0 & lowbyte & sfrbit [ byteaddr = lowbyte + 0x20; ] { export *[RAM]:1 byteaddr; }
@elif defined(MX51)
BitByteAddr: byteaddr is bitbank=0 & lowbyte & sfrbit [ byteaddr = lowbyte + 0x20; ] { tmp:3 = byteaddr + 0x7f0000; export *[RAM]:1 tmp; }
@elif defined(MCS51) || defined(MCS80390)
BitByteAddr: byteaddr is bitbank=0 & lowbyte & sfrbit [ byteaddr = lowbyte + 0x20; ] { export *[INTMEM]:1 byteaddr; }
@endif
@if defined(MCS251) || defined(MX51)
Addr11: relAddr is aopaddr & adata [ relAddr = (inst_next $and 0xfff800)+(aopaddr*256)+adata; ] { export *:1 relAddr; }
Addr16: addr is addr16 [ addr = (inst_next $and 0xff0000) + addr16; ] { export *:1 addr; }
@elif defined(MCS51)
Addr11: relAddr is aopaddr & adata [ relAddr =(inst_next $and 0xf800)+(aopaddr*256)+adata; ] { export *:1 relAddr; }
Addr16: addr16 is addr16 { export *:1 addr16; }
@elif defined(MCS80390)
Addr19: relAddr is aopaddr & adata [ relAddr =(inst_next $and 0xf80000)+(aopaddr*256*256)+adata; ] { export *:1 relAddr; }
Addr24: addr24 is addr24 { export *:1 addr24; }
@endif
Rel8: relAddr is rel8 [ relAddr=inst_next+rel8; ] { export *:1 relAddr; }
Rel16: relAddr is rel16 [ relAddr=inst_next+rel16; ] { export *:1 relAddr; }
@if defined(MCS251)
# detect A5 prefix
:^instruction is phase=0 & ophi=0xa & oplo=0x5; instruction [ phase=1; A5Prefix=1; ] { }
:^instruction is phase=0 & instruction [ phase=1; A5Prefix=0; ] { }
@endif
@if defined(MCS80390)
:ACALL Addr19 is $(GROUP1) & aaddrfill=1 & aoplo=1 & Addr19 { ret:3 = inst_next; push24(ret); call Addr19; }
@else
:ACALL Addr11 is $(GROUP1) & aaddrfill=1 & aoplo=1 & Addr11 { ret:2 = inst_next; push16(ret); call Addr11; }
@endif
:ADD Areg,rn is $(GROUP2) & ophi=2 & Areg & rnfill=1 & rn { addflags(ACC,rn); ACC = ACC + rn; resultflags(ACC); }
:ADD Areg,Direct is $(GROUP1) & ophi=2 & oplo=5 & Areg; Direct { addflags(ACC,Direct); ACC = ACC + Direct; resultflags(ACC); }
:ADD Areg,Ri is $(GROUP2) & ophi=2 & Areg & rifill=3 & Ri { addflags(ACC,Ri); ACC = ACC + Ri; resultflags(ACC); }
:ADD Areg,Data is $(GROUP1) & ophi=2 & oplo=4 & Areg; Data { addflags(ACC,Data); ACC = ACC + Data; resultflags(ACC); }
:ADDC Areg,rn is $(GROUP2) & ophi=3 & Areg & rnfill=1 & rn { tmp:1 =$(CY)+ rn; addflags(ACC,tmp); ACC = ACC + tmp; resultflags(ACC); }
:ADDC Areg,Direct is $(GROUP1) & ophi=3 & oplo=5 & Areg; Direct { tmp:1 =$(CY)+ Direct; addflags(ACC,tmp); ACC = ACC + tmp; resultflags(ACC); }
:ADDC Areg,Ri is $(GROUP2) & ophi=3 & Areg & rifill=3 & Ri { tmp:1 =$(CY)+ Ri; addflags(ACC,tmp); ACC = ACC + tmp; resultflags(ACC); }
:ADDC Areg,Data is $(GROUP1) & ophi=3 & oplo=4 & Areg; Data { tmp:1 =$(CY)+ Data; addflags(ACC,tmp); ACC = ACC + tmp; resultflags(ACC); }
#TODO: which GROUP does AJMP belong to ??
@if defined(MCS80390)
:AJMP Addr19 is $(GROUP1) & aaddrfill=0 & aoplo=1 & Addr19 { goto Addr19; }
@else
:AJMP Addr11 is $(GROUP1) & aaddrfill=0 & aoplo=1 & Addr11 { goto Addr11; }
@endif
:ANL Areg,rn is $(GROUP2) & ophi=5 & Areg & rnfill=1 & rn { ACC = ACC & rn; resultflags(ACC); }
:ANL Areg,Direct is $(GROUP1) & ophi=5 & oplo=5 & Areg; Direct { ACC = ACC & Direct; resultflags(ACC); }
:ANL Areg,Ri is $(GROUP2) & ophi=5 & Areg & rifill=3 & Ri { ACC = ACC & Ri; resultflags(ACC); }
:ANL Areg,Data is $(GROUP2) & ophi=5 & oplo=4 & Areg; Data { ACC = ACC & Data; resultflags(ACC); }
:ANL Direct,Areg is $(GROUP1) & ophi=5 & oplo=2 & Areg; Direct { tmp:1 = Direct & ACC; Direct = tmp; resultflags(tmp); }
:ANL Direct,Data is $(GROUP1) & ophi=5 & oplo=3; Direct; Data { tmp:1 = Direct & Data; Direct = tmp; resultflags(tmp); }
:ANL CY,BitAddr is $(GROUP1) & CY & ophi=8 & oplo=2; BitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & BitByteAddr {tmp:1 = BitByteAddr; $(CY)=$(CY)& ((tmp>>sfrbit)&1); resultflags(tmp); }
:ANL CY,BitAddr2 is $(GROUP1) & CY & ophi=11 & oplo=0; BitAddr2 & bitaddr57=7 & sfrbit3=0 & sfrbit & BitByteAddr {tmp:1 = BitByteAddr; $(CY)=$(CY)& (~((tmp>>sfrbit)&1)); }
@if BIT_OPS == "BIT_ADDRS"
:ANL CY,BitAddr is $(GROUP1) & CY & ophi=8 & oplo=2; BitAddr & sfrbit & BitByteAddr {$(CY)=$(CY)& BitAddr; }
:ANL CY,BitAddr2 is $(GROUP1) & CY & ophi=11 & oplo=0; BitAddr2 & sfrbit & BitByteAddr {$(CY)=$(CY)& ~BitAddr2; }
@elif BIT_OPS == "PCODEOPS"
:ANL CY,BitAddr is $(GROUP1) & CY & ophi=8 & oplo=2; BitAddr & sfrbit & BitByteAddr {$(CY)=$(CY)& get(BitAddr, BitByteAddr); }
:ANL CY,BitAddr2 is $(GROUP1) & CY & ophi=11 & oplo=0; BitAddr2 & sfrbit & BitByteAddr {$(CY)=$(CY)& (get(BitAddr2, BitByteAddr)^1); }
@elif BIT_OPS == "SHIFTS"
:ANL CY,BitAddr is $(GROUP1) & CY & ophi=8 & oplo=2; BitAddr & sfrbit & BitByteAddr {$(CY)=$(CY)& ((BitByteAddr>>sfrbit)&1); }
:ANL CY,BitAddr2 is $(GROUP1) & CY & ophi=11 & oplo=0; BitAddr2 & sfrbit & BitByteAddr {$(CY)=$(CY)& (~((BitByteAddr>>sfrbit)&1)); }
@endif
:CJNE Areg,Direct,Rel8 is $(GROUP1) & ophi=11 & oplo=5 & Areg; Direct; Rel8 { compflags(ACC,Direct); if (ACC!=Direct) goto Rel8; }
:CJNE Areg,Data,Rel8 is $(GROUP1) & ophi=11 & oplo=4 & Areg; Data; Rel8 { compflags(ACC,Data); if (ACC!=Data) goto Rel8; }
:CJNE rn,Data,Rel8 is $(GROUP2) & ophi=11 & rnfill=1 & rn; Data; Rel8 { compflags(rn,Data); if (rn!=Data) goto Rel8; }
:CJNE Ri,Data,Rel8 is $(GROUP2) & ophi=11 & rifill=3 & Ri; Data; Rel8 { compflags(Ri,Data); if (Ri!=Data) goto Rel8; }
:CLR Areg is $(GROUP1) & ophi=14 & oplo=4 & Areg { ACC = 0; }
:CLR CY is $(GROUP1) & CY & ophi=12 & oplo=3 {$(CY)= 0; }
:CLR BitAddr is $(GROUP1) & ophi=12 & oplo=2; BitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & BitByteAddr { local tmp = ~(1<<sfrbit); BitByteAddr = BitByteAddr & tmp; }
@if BIT_OPS == "BIT_ADDRS"
:CLR BitAddr is $(GROUP1) & ophi=12 & oplo=2; BitAddr & sfrbit & BitByteAddr { BitAddr = 0; }
@elif BIT_OPS == "PCODEOPS"
:CLR BitAddr is $(GROUP1) & ophi=12 & oplo=2; BitAddr & sfrbit & BitByteAddr { BitByteAddr = clr(BitAddr, BitByteAddr); }
#:CLR PortBit is $(GROUP1) & ophi=12 & oplo=2; PortBit & sfrbit & BitByteAddr { outp(PortBit, 0:1, BitByteAddr); }
@elif BIT_OPS == "SHIFTS"
:CLR BitAddr is $(GROUP1) & ophi=12 & oplo=2; BitAddr & sfrbit & BitByteAddr { local tmp = ~(1<<sfrbit); BitByteAddr = BitByteAddr & tmp; }
@endif
:CPL Areg is $(GROUP2) & ophi=15 & oplo=4 & Areg { ACC = ~ACC; }
:CPL CY is $(GROUP2) & CY & ophi=11 & oplo=3 {$(CY)=$(CY)^ 1; }
:CPL BitAddr is $(GROUP1) & ophi=11 & oplo=2; BitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & BitByteAddr { tmp:1 = (1<<sfrbit); BitByteAddr = BitByteAddr ^ tmp; }
@if BIT_OPS == "BIT_ADDRS"
:CPL BitAddr is $(GROUP1) & ophi=11 & oplo=2; BitAddr & sfrbit & BitByteAddr { BitAddr = BitAddr ^ 1; }
@elif BIT_OPS == "PCODEOPS"
:CPL BitAddr is $(GROUP1) & ophi=11 & oplo=2; BitAddr & sfrbit & BitByteAddr { tmp:1 = get(BitAddr, BitByteAddr) ^ 1; BitByteAddr = set_bit_value(BitAddr, tmp, BitByteAddr); }
@elif BIT_OPS == "SHIFTS"
:CPL BitAddr is $(GROUP1) & ophi=11 & oplo=2; BitAddr & sfrbit & BitByteAddr { tmp:1 = (1<<sfrbit); BitByteAddr = BitByteAddr ^ tmp; }
@endif
:DA Areg is $(GROUP1) & ophi=13 & oplo=4 & Areg { ACC = decimal_adjust(ACC); }
:DEC Areg is $(GROUP1) & ophi=1 & oplo=4 & Areg { ACC = ACC - 1; }
:DEC rn is $(GROUP2) & ophi=1 & rnfill=1 & rn { rn = rn - 1; }
:DEC Direct is $(GROUP1) & ophi=1 & oplo=5; Direct { Direct = Direct - 1; }
:DEC Ri is $(GROUP2) & ophi=1 & rifill=3 & Ri { Ri = Ri - 1; }
:DIV ABreg is $(GROUP1) & ophi=8 & oplo=4 & ABreg { PSW = PSW & 0x7b; tmp : 1 = (B == 0)<<2; PSW = PSW | tmp; if (B==0) goto inst_next; tmp2 : 1 = ACC; ACC = tmp2 / B; B = tmp2 % B; }
# Specifying rnfill here is a temporary to allow distinguishing DJNZ1 and XCHD
:DJNZ rn,Rel8 is $(GROUP2) & ophi=13 & rnfill=1 & rnfill=1 & rn; Rel8 { rn = rn - 1; if (rn!=0) goto Rel8; }
:DJNZ Direct,Rel8 is $(GROUP1) & ophi=13 & oplo=5; Direct; Rel8 { Direct = Direct - 1; if (Direct!=0) goto Rel8; }
:INC Areg is $(GROUP1) & ophi=0 & oplo=4 & Areg { ACC = ACC + 1; }
:INC rn is $(GROUP2) & ophi=0 & rnfill=1 & rn { rn = rn + 1; }
:INC Direct is $(GROUP1) & ophi=0 & oplo=5; Direct { Direct = Direct + 1; }
@if defined(DUAL_DPTR) && defined(DPS_REG_NUM)
:INC Direct is $(GROUP1) & ophi=0 & oplo=5; Direct & direct=$(DPS_REG_NUM) {
AUXR1 = AUXR1 ^ 0x01;
tmp:2 = DPTR;
DPTR = DPTR2;
DPTR2 = tmp;
}
@endif
:INC Ri is $(GROUP2) & ophi=0 & rifill=3 & Ri { Ri = Ri + 1; }
:INC DPTRreg is $(GROUP1) & ophi=10 & oplo=3 & DPTRreg { DPTR = DPTR + 1; }
:JB BitAddr,Rel8 is $(GROUP1) & ophi=2 & oplo=0; BitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & BitByteAddr; Rel8 { if (((BitByteAddr>>sfrbit)&1) == 1:1) goto Rel8; }
:JBC BitAddr,Rel8 is $(GROUP1) & ophi=1 & oplo=0; BitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & BitByteAddr; Rel8 { tmp:1 = 1<<sfrbit; if ((BitByteAddr & tmp)==0) goto inst_next; BitByteAddr = BitByteAddr & ~tmp; goto Rel8; }
@if BIT_OPS == "BIT_ADDRS"
:JB BitAddr,Rel8 is $(GROUP1) & ophi=2 & oplo=0; BitAddr & sfrbit & BitByteAddr; Rel8 { if (BitAddr == 1:1) goto Rel8; }
:JBC BitAddr,Rel8 is $(GROUP1) & ophi=1 & oplo=0; BitAddr & sfrbit & BitByteAddr; Rel8 { if (BitAddr == 0:1) goto inst_next; BitAddr = 0; goto Rel8; }
@elif BIT_OPS == "PCODEOPS"
:JB BitAddr,Rel8 is $(GROUP1) & ophi=2 & oplo=0; BitAddr & sfrbit & BitByteAddr; Rel8 { if (get(BitAddr, BitByteAddr)==1:1) goto Rel8; }
:JBC BitAddr,Rel8 is $(GROUP1) & ophi=1 & oplo=0; BitAddr & sfrbit & BitByteAddr; Rel8 { tmp:1 = get(BitAddr, BitByteAddr); if (tmp==0) goto inst_next; BitByteAddr = clr(BitAddr, BitByteAddr); goto Rel8; }
@elif BIT_OPS == "SHIFTS"
:JB BitAddr,Rel8 is $(GROUP1) & ophi=2 & oplo=0; BitAddr & sfrbit & BitByteAddr; Rel8 { if (((BitByteAddr>>sfrbit)&1) == 1:1) goto Rel8; }
:JBC BitAddr,Rel8 is $(GROUP1) & ophi=1 & oplo=0; BitAddr & sfrbit & BitByteAddr; Rel8 { tmp:1 = 1<<sfrbit; if ((BitByteAddr & tmp)==0) goto inst_next; BitByteAddr = BitByteAddr & ~tmp; goto Rel8; }
@endif
:JC Rel8 is $(GROUP1) & ophi=4 & oplo=0; Rel8 { if ($(CY) != 0) goto Rel8; }
:JMP ADPTR is $(GROUP1) & ophi=7 & oplo=3 & ADPTR { goto [ADPTR]; }
:JNB BitAddr,Rel8 is $(GROUP1) & ophi=3 & oplo=0; BitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & BitByteAddr; Rel8 { if (((BitByteAddr>>sfrbit)&1)==0:1) goto Rel8; }
@if BIT_OPS == "BIT_ADDRS"
:JNB BitAddr,Rel8 is $(GROUP1) & ophi=3 & oplo=0; BitAddr & sfrbit & BitByteAddr; Rel8 { if (BitAddr == 0:1) goto Rel8; }
@elif BIT_OPS == "PCODEOPS"
:JNB BitAddr,Rel8 is $(GROUP1) & ophi=3 & oplo=0; BitAddr & sfrbit & BitByteAddr; Rel8 { if (get(BitAddr, BitByteAddr)==0:1) goto Rel8; }
@elif BIT_OPS == "SHIFTS"
:JNB BitAddr,Rel8 is $(GROUP1) & ophi=3 & oplo=0; BitAddr & sfrbit & BitByteAddr; Rel8 { if (((BitByteAddr>>sfrbit)&1)==0:1) goto Rel8; }
@endif
:JNC Rel8 is $(GROUP1) & ophi=5 & oplo=0; Rel8 { if ($(CY) == 0) goto Rel8; }
:JNZ Rel8 is $(GROUP1) & ophi=7 & oplo=0; Rel8 { if (ACC != 0) goto Rel8; }
:JZ Rel8 is $(GROUP1) & ophi=6 & oplo=0; Rel8 { if (ACC == 0) goto Rel8; }
@if defined(MCS80390)
:LCALL Addr24 is $(GROUP1) & ophi=1 & oplo=2; Addr24 { ret:$(PTRSIZE) = inst_next; push24(ret); call Addr24; }
:LJMP Addr24 is $(GROUP1) & ophi=0 & oplo=2; Addr24 { goto Addr24; }
@elif defined(MX51)
:LCALL Addr16 is $(GROUP1) & ophi=1 & oplo=2; Addr16 { ret:2 = inst_next; push16(ret); call Addr16; }
:LJMP Addr16 is $(GROUP1) & ophi=0 & oplo=2; Addr16 { goto Addr16; }
@else
:LCALL Addr16 is $(GROUP1) & ophi=1 & oplo=2; Addr16 { ret:$(PTRSIZE) = inst_next; push16(ret); call Addr16; }
:LJMP Addr16 is $(GROUP1) & ophi=0 & oplo=2; Addr16 { goto Addr16; }
@endif
:MOV Areg,rn is $(GROUP2) & ophi=14 & rnfill=1 & rn & Areg { ACC = rn; }
:MOV Areg,Direct is $(GROUP1) & ophi=14 & oplo=5 & Areg; Direct { ACC = Direct; }
:MOV Areg,Ri is $(GROUP2) & ophi=14 & Areg & rifill=3 & Ri { ACC = Ri; }
:MOV Areg,Data is $(GROUP1) & ophi=7 & oplo=4 & Areg; Data { ACC = Data; }
:MOV rn,Areg is $(GROUP2) & ophi=15 & rnfill=1 & rn & Areg { rn = ACC; }
:MOV rn,Direct is $(GROUP2) & ophi=10 & rnfill=1 & rn; Direct { rn = Direct; }
:MOV rn,Data is $(GROUP2) & ophi=7 & rnfill=1 & rn; Data { rn = Data; }
:MOV Direct,Areg is $(GROUP1) & ophi=15 & oplo=5 & Areg; Direct { Direct = ACC; }
:MOV Direct,rn is $(GROUP2) & ophi=8 & rnfill=1 & rn; Direct { Direct = rn; }
:MOV Direct2,Direct is $(GROUP1) & ophi=8 & oplo=5; Direct; Direct2 { Direct2 = Direct; }
:MOV Direct,Ri is $(GROUP2) & ophi=8 & rifill=3 & Ri; Direct { Direct = Ri; }
:MOV Direct,Data is $(GROUP1) & ophi=7 & oplo=5; Direct; Data { Direct = Data; }
:MOV Ri,Areg is $(GROUP2) & ophi=15 & rifill=3 & Ri & Areg { Ri = ACC; }
:MOV Ri,Direct is $(GROUP2) & ophi=10 & rifill=3 & Ri; Direct { Ri = Direct; }
:MOV Ri,Data is $(GROUP2) & ophi=7 & rifill=3 & Ri; Data { Ri = Data; }
@if defined(MCS80390)
:MOV DPTRreg,Data24 is $(GROUP1) & ophi=9 & oplo=0 & DPTRreg; Data24 { DPTR = Data24; }
@else
:MOV DPTRreg,Data16 is $(GROUP1) & ophi=9 & oplo=0 & DPTRreg; Data16 { DPTR = Data16; }
@endif
:MOV CY,BitAddr is $(GROUP1) & CY & ophi=10 & oplo=2; BitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & BitByteAddr {$(CY)= (BitByteAddr>>sfrbit)&1; }
:MOV BitAddr,CY is $(GROUP1) & CY & ophi=9 & oplo=2; BitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & BitByteAddr { BitByteAddr = BitByteAddr & (~(1<<sfrbit)); BitByteAddr = BitByteAddr | ($(CY)<<sfrbit); }
@if BIT_OPS == "BIT_ADDRS"
:MOV CY,BitAddr is $(GROUP1) & CY & ophi=10 & oplo=2; BitAddr & sfrbit & BitByteAddr {$(CY)= BitAddr; }
:MOV BitAddr,CY is $(GROUP1) & CY & ophi=9 & oplo=2; BitAddr & sfrbit & BitByteAddr { BitAddr = $(CY); }
@elif BIT_OPS == "PCODEOPS"
:MOV CY,BitAddr is $(GROUP1) & CY & ophi=10 & oplo=2; BitAddr & sfrbit & BitByteAddr {$(CY) = get(BitAddr, BitByteAddr); }
:MOV BitAddr,CY is $(GROUP1) & CY & ophi=9 & oplo=2; BitAddr & sfrbit & BitByteAddr { BitByteAddr = set_bit_value(BitAddr, $(CY), BitByteAddr); }
@elif BIT_OPS == "SHIFTS"
:MOV CY,BitAddr is $(GROUP1) & CY & ophi=10 & oplo=2; BitAddr & sfrbit & BitByteAddr{$(CY)= (BitByteAddr>>sfrbit)&1; }
:MOV BitAddr,CY is $(GROUP1) & CY & ophi=9 & oplo=2; BitAddr & sfrbit & BitByteAddr { BitByteAddr = BitByteAddr & (~(1<<sfrbit)); BitByteAddr = BitByteAddr | ($(CY)<<sfrbit); }
@endif
:MOVC Areg,ADPTR is $(GROUP1) & ophi=9 & oplo=3 & ADPTR & Areg { ACC = *:1 ADPTR; }
:MOVC Areg,APC is $(GROUP1) & ophi=8 & oplo=3 & APC & Areg { ACC = *:1 APC; }
:MOVX Areg,RiX is $(GROUP2) & ophi=14 & rifill=1 & RiX & Areg { ACC = RiX; }
:MOVX Areg,ATDPTR is $(GROUP1) & ophi=14 & oplo=0 & Areg & ATDPTR { ACC = ATDPTR; }
:MOVX RiX,Areg is $(GROUP2) & ophi=15 & rifill=1 & RiX & Areg { RiX = ACC; }
:MOVX ATDPTR,Areg is $(GROUP1) & ophi=15 & oplo=0 & Areg & ATDPTR { ATDPTR = ACC; }
:MUL ABreg is $(GROUP1) & ophi=10 & oplo=4 & ABreg { PSW = PSW & 0x7b; tmp:2 = zext(ACC) * zext(B); ACC = tmp(0); B = tmp(1); PSW = PSW | ((B!=0)<<2); }
#:MUL Areg,Breg is $(GROUP1) & ophi=10 & oplo=4 & Areg & Breg { PSW = PSW & 0x7b; tmp:2 = zext(ACC) * zext(B); ACC = tmp(0); B = tmp(1); PSW = PSW | ((B!=0)<<2); }
:NOP is $(GROUP1) & ophi=0 & oplo=0 { nop(); }
:ORL Areg,rn is $(GROUP2) & ophi=4 & rnfill=1 & rn & Areg { ACC = ACC | rn; }
:ORL Areg,Direct is $(GROUP1) & ophi=4 & oplo=5 & Areg; Direct { ACC = ACC | Direct; }
:ORL Areg,Ri is $(GROUP2) & ophi=4 & Areg & rifill=3 & Ri { ACC = ACC | Ri; }
:ORL Areg,Data is $(GROUP1) & ophi=4 & oplo=4 & Areg; Data { ACC = ACC | Data; }
:ORL Direct,Areg is $(GROUP1) & ophi=4 & oplo=2 & Areg; Direct { Direct = Direct | ACC; }
:ORL Direct,Data is $(GROUP1) & ophi=4 & oplo=3 & Areg; Direct; Data { Direct = Direct | Data; }
:ORL CY,BitAddr is $(GROUP1) & CY & ophi=7 & oplo=2; BitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & BitByteAddr {$(CY)=$(CY)| ((BitByteAddr>>sfrbit)&1); }
:ORL CY,BitAddr2 is $(GROUP1) & CY & ophi=10 & oplo=0; BitAddr2 & bitaddr57=7 & sfrbit3=0 & sfrbit & BitByteAddr {$(CY)=$(CY)| (((BitByteAddr>>sfrbit)&1)^1); }
@if BIT_OPS == "BIT_ADDRS"
:ORL CY,BitAddr is $(GROUP1) & CY & ophi=7 & oplo=2; BitAddr & sfrbit & BitByteAddr {$(CY)=$(CY)| BitAddr; }
:ORL CY,BitAddr2 is $(GROUP1) & CY & ophi=10 & oplo=0; BitAddr2 & sfrbit & BitByteAddr {$(CY)=$(CY)| (BitAddr2^1); }
@elif BIT_OPS == "PCODEOPS"
:ORL CY,BitAddr is $(GROUP1) & CY & ophi=7 & oplo=2; BitAddr & sfrbit & BitByteAddr {$(CY)=$(CY)| get(BitAddr, BitByteAddr); }
:ORL CY,BitAddr2 is $(GROUP1) & CY & ophi=10 & oplo=0; BitAddr2 & sfrbit & BitByteAddr {$(CY)=$(CY)| (get(BitAddr2, BitByteAddr)^1); }
@elif BIT_OPS == "SHIFTS"
:ORL CY,BitAddr is $(GROUP1) & CY & ophi=7 & oplo=2; BitAddr & sfrbit & BitByteAddr {$(CY)=$(CY)| ((BitByteAddr>>sfrbit)&1); }
:ORL CY,BitAddr2 is $(GROUP1) & CY & ophi=10 & oplo=0; BitAddr2 & sfrbit & BitByteAddr {$(CY)=$(CY)| (((BitByteAddr>>sfrbit)&1)^1); }
@endif
:POP Direct is $(GROUP1) & ophi=13 & oplo=0; Direct { pop8(Direct); }
:PUSH Direct is $(GROUP1) & ophi=12 & oplo=0; Direct { push8(Direct); }
:RET is $(GROUP1) & ophi=2 & oplo=2 {
@if defined(MCS251) || defined(MX51)
pc:2 = 0; pop16(pc); pc3:3 = (inst_next & 0xff0000) + zext(pc); return[pc3];
@elif defined(MCS51)
pc:2 = 0; pop16(pc); return[pc];
@elif defined(MCS80390)
pc:3 = 0; pop24(pc); return[pc];
@endif
}
:RETI is $(GROUP1) & ophi=3 & oplo=2 {
@if defined(MCS251) || defined(MX51)
pc:2 = 0; pop16(pc); pc3:3 = (inst_next & 0xff0000) + zext(pc); return[pc3];
@elif defined(MCS51)
pc:2 = 0; pop16(pc); return[pc];
@elif defined(MCS80390)
pc:3 = 0; pop24(pc); return[pc];
@endif
}
:RL Areg is $(GROUP1) & ophi=2 & oplo=3 & Areg { ACC = (ACC<<1) | (ACC>>7); }
:RLC Areg is $(GROUP1) & ophi=3 & oplo=3 & Areg { tmp : 1 = (ACC&0x80)>>7; ACC = (ACC<<1) | $(CY);$(CY)= tmp; }
:RR Areg is $(GROUP1) & ophi=0 & oplo=3 & Areg { ACC = (ACC>>1) | (ACC<<7); }
:RRC Areg is $(GROUP1) & ophi=1 & oplo=3 & Areg { tmp : 1 = ACC&1; ACC = (ACC>>1) | ($(CY)<<7);$(CY)= tmp; }
:SETB CY is $(GROUP1) & CY & ophi=13 & oplo=3 { $(CY)=1; }
:SETB BitAddr is $(GROUP1) & ophi=13 & oplo=2; BitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & BitByteAddr { BitByteAddr = BitByteAddr | (1<<sfrbit); }
@if BIT_OPS == "BIT_ADDRS"
:SETB BitAddr is $(GROUP1) & ophi=13 & oplo=2; BitAddr & sfrbit & BitByteAddr { BitAddr = 1; }
@elif BIT_OPS == "PCODEOPS"
:SETB BitAddr is $(GROUP1) & ophi=13 & oplo=2; BitAddr & sfrbit & BitByteAddr { BitByteAddr = set(BitAddr, BitByteAddr); }
@elif BIT_OPS == "SHIFTS"
:SETB BitAddr is $(GROUP1) & ophi=13 & oplo=2; BitAddr & sfrbit & BitByteAddr { BitByteAddr = BitByteAddr | (1<<sfrbit); }
@endif
:SJMP Rel8 is $(GROUP1) & ophi=8 & oplo=0; Rel8 { goto Rel8; }
:SUBB Areg,rn is $(GROUP2) & ophi=9 & rnfill=1 & rn & Areg { tmp : 1 = rn+$(CY); subflags(ACC,tmp); ACC = ACC - tmp; }
:SUBB Areg,Direct is $(GROUP1) & ophi=9 & oplo=5 & Areg; Direct { tmp:1 = Direct+$(CY); subflags(ACC,tmp); ACC = ACC - tmp; }
:SUBB Areg,Ri is $(GROUP2) & ophi=9 & Areg & rifill=3 & Ri { local tmp = Ri+$(CY); subflags(ACC,tmp); ACC = ACC - tmp; }
:SUBB Areg,Data is $(GROUP1) & ophi=9 & oplo=4 & Areg; Data { tmp:1 = Data+$(CY); subflags(ACC,tmp); ACC = ACC - tmp; }
:SWAP Areg is $(GROUP1) & ophi=12 & oplo=4 & Areg { ACC = (ACC>>4) | (ACC<<4); }
:XCH Areg,rn is $(GROUP2) & ophi=12 & rnfill=1 & rn & Areg { tmp : 1 = ACC; ACC = rn; rn = tmp; }
:XCH Areg,Direct is $(GROUP1) & ophi=12 & oplo=5 & Areg; Direct { tmp : 1 = ACC; ACC = Direct; Direct = tmp; }
:XCH Areg,Ri is $(GROUP2) & ophi=12 & rifill=3 & Ri & Areg { tmp : 1 = ACC; ACC = Ri; Ri = tmp; }
# TODO: This instruction appears to be in both GROUP2 & GROUP3 (always available)
:XCHD Areg,Ri is ophi=13 & Areg & rifill=3 & Ri { tmp : 1 = ACC & 0xf; ACC = (ACC&0xf0) | (Ri&0xf); Ri = (Ri&0xf0) | tmp; }
:XRL Areg,rn is $(GROUP2) & ophi=6 & rnfill=1 & rn & Areg { ACC = ACC ^ rn; }
:XRL Areg,Direct is $(GROUP1) & ophi=6 & oplo=5 & Areg; Direct { ACC = ACC ^ Direct; }
:XRL Areg,Ri is $(GROUP2) & ophi=6 & rifill=3 & Ri & Areg { ACC = ACC ^ Ri; }
:XRL Areg,Data is $(GROUP1) & ophi=6 & oplo=4 & Areg; Data { ACC = ACC ^ Data; }
:XRL Direct,Areg is $(GROUP1) & ophi=6 & oplo=2 & Areg; Direct { Direct = Direct ^ ACC; }
:XRL Direct,Data is $(GROUP1) & ophi=6 & oplo=3; Direct; Data { Direct = Direct ^ Data; }
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="UTF-8"?>
<compiler_spec>
<global>
<range space="RAM"/>
<range space="SFR"/>
<range space="ESFR"/>
<range space="BITS"/>
<range space="EBITS"/>
</global>
<stackpointer register="SP" space="RAM" growth="positive"/>
<default_proto>
<!-- Removed push / pop around calls to clear up decompilation -->
<prototype name="__keilmxs3" extrapop="0" stackshift="0" strategy="register">
<input>
<pentry minsize="1" maxsize="2">
<register name="R6R7"/>
</pentry>
<pentry minsize="1" maxsize="2">
<register name="R4R5"/>
</pentry>
<pentry minsize="1" maxsize="2">
<!-- Expect to see R3R2R1 as an endian swapped pointer a lot -->
<register name="R2R3"/>
</pentry>
</input>
<output>
<pentry minsize="1" maxsize="2">
<register name="R6R7"/>
</pentry>
</output>
<unaffected>
<register name="SP"/>
</unaffected>
<localrange>
<range space="stack" first="0x1" last="0x0fc"/>
</localrange>
<!-- <localrange> -->
<!-- <range space="stack" first="0x0" last="0xf"/> -->
<!-- </localrange> -->
</prototype>
</default_proto>
<!-- Add in additional Keil prototypes -->
<prototype name="__keilmxs2p1" extrapop="0" stackshift="0" strategy="register">
<input>
<pentry minsize="1" maxsize="2">
<register name="R6R7"/>
</pentry>
<pentry minsize="1" maxsize="2">
<register name="R4R5"/>
</pentry>
<pentry minsize="3" maxsize="3">
<!-- Technically will be endian swapped -->
<register name="R1R2R3"/>
</pentry>
</input>
<output>
<pentry minsize="1" maxsize="2">
<register name="R6R7"/>
</pentry>
</output>
<unaffected>
<register name="SP"/>
</unaffected>
<localrange>
<range space="stack" first="0x1" last="0x0fc"/>
</localrange>
<!-- <localrange> -->
<!-- <range space="stack" first="0x0" last="0xf"/> -->
<!-- </localrange> -->
</prototype>
</compiler_spec>
@@ -0,0 +1,423 @@
<?xml version="1.0" encoding="UTF-8"?>
<processor_spec>
<programcounter register="PC"/>
<volatile outputop="write_volatile" inputop="read_volatile">
<range space="SFR" first="0x0" last="0xFF"/>
<range space="BITS" first="0x80" last="0xFF"/>
</volatile>
<default_symbols>
<symbol name="BANK0_R0" address="RAM:7f0000"/>
<symbol name="BANK0_R1" address="RAM:7f0001"/>
<symbol name="BANK0_R2" address="RAM:7f0002"/>
<symbol name="BANK0_R3" address="RAM:7f0003"/>
<symbol name="BANK0_R4" address="RAM:7f0004"/>
<symbol name="BANK0_R5" address="RAM:7f0005"/>
<symbol name="BANK0_R6" address="RAM:7f0006"/>
<symbol name="BANK0_R7" address="RAM:7f0007"/>
<symbol name="BANK1_R0" address="RAM:7f0008"/>
<symbol name="BANK1_R1" address="RAM:7f0009"/>
<symbol name="BANK1_R2" address="RAM:7f000a"/>
<symbol name="BANK1_R3" address="RAM:7f000b"/>
<symbol name="BANK1_R4" address="RAM:7f000c"/>
<symbol name="BANK1_R5" address="RAM:7f000d"/>
<symbol name="BANK1_R6" address="RAM:7f000e"/>
<symbol name="BANK1_R7" address="RAM:7f000f"/>
<symbol name="BANK2_R0" address="RAM:7f0010"/>
<symbol name="BANK2_R1" address="RAM:7f0011"/>
<symbol name="BANK2_R2" address="RAM:7f0012"/>
<symbol name="BANK2_R3" address="RAM:7f0013"/>
<symbol name="BANK2_R4" address="RAM:7f0014"/>
<symbol name="BANK2_R5" address="RAM:7f0015"/>
<symbol name="BANK2_R6" address="RAM:7f0016"/>
<symbol name="BANK2_R7" address="RAM:7f0017"/>
<symbol name="BANK3_R0" address="RAM:7f0018"/>
<symbol name="BANK3_R1" address="RAM:7f0019"/>
<symbol name="BANK3_R2" address="RAM:7f001a"/>
<symbol name="BANK3_R3" address="RAM:7f001b"/>
<symbol name="BANK3_R4" address="RAM:7f001c"/>
<symbol name="BANK3_R5" address="RAM:7f001d"/>
<symbol name="BANK3_R6" address="RAM:7f001e"/>
<symbol name="BANK3_R7" address="RAM:7f001f"/>
<symbol name="P0" address="SFR:80"/>
<symbol name="SP" address="SFR:81"/>
<symbol name="DPL" address="SFR:82"/>
<symbol name="DPH" address="SFR:83"/>
<symbol name="DPXL" address="SFR:84"/>
<symbol name="PCON" address="SFR:87"/>
<symbol name="TCON" address="SFR:88"/>
<symbol name="TMOD" address="SFR:89"/>
<symbol name="TL0" address="SFR:8a"/>
<symbol name="TL1" address="SFR:8b"/>
<symbol name="TH0" address="SFR:8c"/>
<symbol name="TH1" address="SFR:8d"/>
<symbol name="FADDR" address="SFR:8f"/>
<symbol name="P1" address="SFR:90"/>
<symbol name="DPX" address="SFR:93"/>
<symbol name="HADDR" address="SFR:97"/>
<symbol name="SCON" address="SFR:98"/>
<symbol name="SBUF" address="SFR:99"/>
<symbol name="P2" address="SFR:a0"/>
<symbol name="HIE" address="SFR:a1"/>
<symbol name="FIE" address="SFR:a2"/>
<symbol name="FIE1" address="SFR:a3"/>
<symbol name="WDTRST" address="SFR:a6"/>
<symbol name="WCON" address="SFR:a7"/>
<symbol name="IE" address="SFR:a8"/>
<symbol name="SADDR" address="SFR:a9"/>
<symbol name="HSTAT" address="SFR:ae"/>
<symbol name="P3" address="SFR:b0"/>
<symbol name="IEN1" address="SFR:b1"/>
<symbol name="IPL1" address="SFR:b2"/>
<symbol name="IPH1" address="SFR:b3"/>
<symbol name="IPH0" address="SFR:b7"/>
<symbol name="IP" address="SFR:b8"/>
<symbol name="SADEN" address="SFR:b9"/>
<symbol name="SPH" address="SFR:be"/>
<symbol name="FIFLG" address="SFR:c0"/>
<symbol name="FIFLG1" address="SFR:c1"/>
<symbol name="EPCONFIG" address="SFR:c7"/>
<symbol name="T2CON" address="SFR:c8"/>
<symbol name="T2MOD" address="SFR:c9"/>
<symbol name="RCAP2L" address="SFR:ca"/>
<symbol name="RCAP2H" address="SFR:cb"/>
<symbol name="TL2" address="SFR:cc"/>
<symbol name="TH2" address="SFR:cd"/>
<symbol name="HPCON" address="SFR:cf"/>
<symbol name="PSW" address="SFR:d0"/>
<symbol name="PSW1" address="SFR:d1"/>
<symbol name="SOFL" address="SFR:d2"/>
<symbol name="HPINDEX" address="SFR:d4"/>
<symbol name="HPSC" address="SFR:d5"/>
<symbol name="HPSTAT" address="SFR:d7"/>
<symbol name="CCON" address="SFR:d8"/>
<symbol name="CMOD" address="SFR:d9"/>
<symbol name="CCAPM0" address="SFR:da"/>
<symbol name="CCAPM1" address="SFR:db"/>
<symbol name="CCAPM2" address="SFR:dc"/>
<symbol name="CCAPM3" address="SFR:dd"/>
<symbol name="CCAPM4" address="SFR:de"/>
<symbol name="PCON1" address="SFR:df"/>
<symbol name="ACC" address="SFR:e0"/>
<symbol name="EPCON" address="SFR:e1"/>
<symbol name="RXSTAT" address="SFR:e2"/>
<symbol name="RXDAT" address="SFR:e3"/>
<symbol name="RXCON" address="SFR:e4"/>
<symbol name="RXFLG" address="SFR:e5"/>
<symbol name="RXCNTL" address="SFR:e6"/>
<symbol name="RXCNTH" address="SFR:e7"/>
<symbol name="HIFLG" address="SFR:e8"/>
<symbol name="CL" address="SFR:e9"/>
<symbol name="CCAP0L" address="SFR:ea"/>
<symbol name="CCAP1L" address="SFR:eb"/>
<symbol name="CCAP2L" address="SFR:ec"/>
<symbol name="CCAP3L" address="SFR:ed"/>
<symbol name="CCAP4L" address="SFR:ee"/>
<symbol name="B" address="SFR:f0"/>
<symbol name="EPINDEX" address="SFR:f1"/>
<symbol name="TXSTAT" address="SFR:f2"/>
<symbol name="TXDAT" address="SFR:f3"/>
<symbol name="TXCON" address="SFR:f4"/>
<symbol name="TXFLG" address="SFR:f5"/>
<symbol name="TXCNTL" address="SFR:f6"/>
<symbol name="TXCNTH" address="SFR:f7"/>
<symbol name="CH" address="SFR:f9"/>
<symbol name="CCAP0H" address="SFR:fa"/>
<symbol name="CCAP1H" address="SFR:fb"/>
<symbol name="CCAP2H" address="SFR:fc"/>
<symbol name="CCAP3H" address="SFR:fd"/>
<symbol name="CCAP4H" address="SFR:fe"/>
<symbol name="SPE" address="ESFR:fb"/>
<symbol name="EPL" address="ESFR:fc"/>
<symbol name="EPM" address="ESFR:fd"/>
<symbol name="EPH" address="ESFR:fe"/>
<symbol name="MXCON" address="ESFR:ff"/>
<symbol name="20.0" address="BITS:00"/>
<symbol name="20.1" address="BITS:01"/>
<symbol name="20.2" address="BITS:02"/>
<symbol name="20.3" address="BITS:03"/>
<symbol name="20.4" address="BITS:04"/>
<symbol name="20.5" address="BITS:05"/>
<symbol name="20.6" address="BITS:06"/>
<symbol name="20.7" address="BITS:07"/>
<symbol name="21.0" address="BITS:08"/>
<symbol name="21.1" address="BITS:09"/>
<symbol name="21.2" address="BITS:0a"/>
<symbol name="21.3" address="BITS:0b"/>
<symbol name="21.4" address="BITS:0c"/>
<symbol name="21.5" address="BITS:0d"/>
<symbol name="21.6" address="BITS:0e"/>
<symbol name="21.7" address="BITS:0f"/>
<symbol name="22.0" address="BITS:10"/>
<symbol name="22.1" address="BITS:11"/>
<symbol name="22.2" address="BITS:12"/>
<symbol name="22.3" address="BITS:13"/>
<symbol name="22.4" address="BITS:14"/>
<symbol name="22.5" address="BITS:15"/>
<symbol name="22.6" address="BITS:16"/>
<symbol name="22.7" address="BITS:17"/>
<symbol name="23.0" address="BITS:18"/>
<symbol name="23.1" address="BITS:19"/>
<symbol name="23.2" address="BITS:1a"/>
<symbol name="23.3" address="BITS:1b"/>
<symbol name="23.4" address="BITS:1c"/>
<symbol name="23.5" address="BITS:1d"/>
<symbol name="23.6" address="BITS:1e"/>
<symbol name="23.7" address="BITS:1f"/>
<symbol name="24.0" address="BITS:20"/>
<symbol name="24.1" address="BITS:21"/>
<symbol name="24.2" address="BITS:22"/>
<symbol name="24.3" address="BITS:23"/>
<symbol name="24.4" address="BITS:24"/>
<symbol name="24.5" address="BITS:25"/>
<symbol name="24.6" address="BITS:26"/>
<symbol name="24.7" address="BITS:27"/>
<symbol name="25.0" address="BITS:28"/>
<symbol name="25.1" address="BITS:29"/>
<symbol name="25.2" address="BITS:2a"/>
<symbol name="25.3" address="BITS:2b"/>
<symbol name="25.4" address="BITS:2c"/>
<symbol name="25.5" address="BITS:2d"/>
<symbol name="25.6" address="BITS:2e"/>
<symbol name="25.7" address="BITS:2f"/>
<symbol name="26.0" address="BITS:30"/>
<symbol name="26.1" address="BITS:31"/>
<symbol name="26.2" address="BITS:32"/>
<symbol name="26.3" address="BITS:33"/>
<symbol name="26.4" address="BITS:34"/>
<symbol name="26.5" address="BITS:35"/>
<symbol name="26.6" address="BITS:36"/>
<symbol name="26.7" address="BITS:37"/>
<symbol name="27.0" address="BITS:38"/>
<symbol name="27.1" address="BITS:39"/>
<symbol name="27.2" address="BITS:3a"/>
<symbol name="27.3" address="BITS:3b"/>
<symbol name="27.4" address="BITS:3c"/>
<symbol name="27.5" address="BITS:3d"/>
<symbol name="27.6" address="BITS:3e"/>
<symbol name="27.7" address="BITS:3f"/>
<symbol name="28.0" address="BITS:40"/>
<symbol name="28.1" address="BITS:41"/>
<symbol name="28.2" address="BITS:42"/>
<symbol name="28.3" address="BITS:43"/>
<symbol name="28.4" address="BITS:44"/>
<symbol name="28.5" address="BITS:45"/>
<symbol name="28.6" address="BITS:46"/>
<symbol name="28.7" address="BITS:47"/>
<symbol name="29.0" address="BITS:48"/>
<symbol name="29.1" address="BITS:49"/>
<symbol name="29.2" address="BITS:4a"/>
<symbol name="29.3" address="BITS:4b"/>
<symbol name="29.4" address="BITS:4c"/>
<symbol name="29.5" address="BITS:4d"/>
<symbol name="29.6" address="BITS:4e"/>
<symbol name="29.7" address="BITS:4f"/>
<symbol name="2a.0" address="BITS:50"/>
<symbol name="2a.1" address="BITS:51"/>
<symbol name="2a.2" address="BITS:52"/>
<symbol name="2a.3" address="BITS:53"/>
<symbol name="2a.4" address="BITS:54"/>
<symbol name="2a.5" address="BITS:55"/>
<symbol name="2a.6" address="BITS:56"/>
<symbol name="2a.7" address="BITS:57"/>
<symbol name="2b.0" address="BITS:58"/>
<symbol name="2b.1" address="BITS:59"/>
<symbol name="2b.2" address="BITS:5a"/>
<symbol name="2b.3" address="BITS:5b"/>
<symbol name="2b.4" address="BITS:5c"/>
<symbol name="2b.5" address="BITS:5d"/>
<symbol name="2b.6" address="BITS:5e"/>
<symbol name="2b.7" address="BITS:5f"/>
<symbol name="2c.0" address="BITS:60"/>
<symbol name="2c.1" address="BITS:61"/>
<symbol name="2c.2" address="BITS:62"/>
<symbol name="2c.3" address="BITS:63"/>
<symbol name="2c.4" address="BITS:64"/>
<symbol name="2c.5" address="BITS:65"/>
<symbol name="2c.6" address="BITS:66"/>
<symbol name="2c.7" address="BITS:67"/>
<symbol name="2d.0" address="BITS:68"/>
<symbol name="2d.1" address="BITS:69"/>
<symbol name="2d.2" address="BITS:6a"/>
<symbol name="2d.3" address="BITS:6b"/>
<symbol name="2d.4" address="BITS:6c"/>
<symbol name="2d.5" address="BITS:6d"/>
<symbol name="2d.6" address="BITS:6e"/>
<symbol name="2d.7" address="BITS:6f"/>
<symbol name="2e.0" address="BITS:70"/>
<symbol name="2e.1" address="BITS:71"/>
<symbol name="2e.2" address="BITS:72"/>
<symbol name="2e.3" address="BITS:73"/>
<symbol name="2e.4" address="BITS:74"/>
<symbol name="2e.5" address="BITS:75"/>
<symbol name="2e.6" address="BITS:76"/>
<symbol name="2e.7" address="BITS:77"/>
<symbol name="2f.0" address="BITS:78"/>
<symbol name="2f.1" address="BITS:79"/>
<symbol name="2f.2" address="BITS:7a"/>
<symbol name="2f.3" address="BITS:7b"/>
<symbol name="2f.4" address="BITS:7c"/>
<symbol name="2f.5" address="BITS:7d"/>
<symbol name="2f.6" address="BITS:7e"/>
<symbol name="2f.7" address="BITS:7f"/>
<symbol name="P0.0" address="BITS:80"/>
<symbol name="P0.1" address="BITS:81"/>
<symbol name="P0.2" address="BITS:82"/>
<symbol name="P0.3" address="BITS:83"/>
<symbol name="P0.4" address="BITS:84"/>
<symbol name="P0.5" address="BITS:85"/>
<symbol name="P0.6" address="BITS:86"/>
<symbol name="P0.7" address="BITS:87"/>
<symbol name="IT0" address="BITS:88"/>
<symbol name="IE0" address="BITS:89"/>
<symbol name="IT1" address="BITS:8a"/>
<symbol name="IE1" address="BITS:8b"/>
<symbol name="TR0" address="BITS:8c"/>
<symbol name="TF0" address="BITS:8d"/>
<symbol name="TR1" address="BITS:8e"/>
<symbol name="TF1" address="BITS:8f"/>
<symbol name="P1.0" address="BITS:90"/>
<symbol name="P1.1" address="BITS:91"/>
<symbol name="P1.2" address="BITS:92"/>
<symbol name="P1.3" address="BITS:93"/>
<symbol name="P1.4" address="BITS:94"/>
<symbol name="P1.5" address="BITS:95"/>
<symbol name="P1.6" address="BITS:96"/>
<symbol name="P1.7" address="BITS:97"/>
<symbol name="RI" address="BITS:98"/>
<symbol name="TI" address="BITS:99"/>
<symbol name="RB8" address="BITS:9a"/>
<symbol name="TB8" address="BITS:9b"/>
<symbol name="REN" address="BITS:9c"/>
<symbol name="SM2" address="BITS:9d"/>
<symbol name="SM1" address="BITS:9e"/>
<symbol name="SM0" address="BITS:9f"/>
<symbol name="P2.0" address="BITS:a0"/>
<symbol name="P2.1" address="BITS:a1"/>
<symbol name="P2.2" address="BITS:a2"/>
<symbol name="P2.3" address="BITS:a3"/>
<symbol name="P2.4" address="BITS:a4"/>
<symbol name="P2.5" address="BITS:a5"/>
<symbol name="P2.6" address="BITS:a6"/>
<symbol name="P2.7" address="BITS:a7"/>
<symbol name="EX0" address="BITS:a8"/>
<symbol name="ET0" address="BITS:a9"/>
<symbol name="EX1" address="BITS:aa"/>
<symbol name="ET1" address="BITS:ab"/>
<symbol name="ES" address="BITS:ac"/>
<symbol name="ET2" address="BITS:ad"/>
<symbol name="EC" address="BITS:ae"/>
<symbol name="EA" address="BITS:af"/>
<symbol name="RXD" address="BITS:b0"/>
<symbol name="TXD" address="BITS:b1"/>
<symbol name="INT0" address="BITS:b2"/>
<symbol name="INT1" address="BITS:b3"/>
<symbol name="T0" address="BITS:b4"/>
<symbol name="T1" address="BITS:b5"/>
<symbol name="WR" address="BITS:b6"/>
<symbol name="RD" address="BITS:b7"/>
<symbol name="PX0" address="BITS:b8"/>
<symbol name="PT0" address="BITS:b9"/>
<symbol name="PX1" address="BITS:ba"/>
<symbol name="PT1" address="BITS:bb"/>
<symbol name="PS" address="BITS:bc"/>
<symbol name="PT2" address="BITS:bd"/>
<symbol name="PC" address="BITS:be"/>
<symbol name="IP.7" address="BITS:bf"/>
<symbol name="FIFLG.0" address="BITS:c0"/>
<symbol name="FIFLG.1" address="BITS:c1"/>
<symbol name="FIFLG.2" address="BITS:c2"/>
<symbol name="FIFLG.3" address="BITS:c3"/>
<symbol name="FIFLG.4" address="BITS:c4"/>
<symbol name="FIFLG.5" address="BITS:c5"/>
<symbol name="FIFLG.6" address="BITS:c6"/>
<symbol name="FIFLG.7" address="BITS:c7"/>
<symbol name="CPRL2" address="BITS:c8"/>
<symbol name="CT2" address="BITS:c9"/>
<symbol name="TR2" address="BITS:ca"/>
<symbol name="EXEN2" address="BITS:cb"/>
<symbol name="TCLK" address="BITS:cc"/>
<symbol name="RCLK" address="BITS:cd"/>
<symbol name="EXF2" address="BITS:ce"/>
<symbol name="TF2" address="BITS:cf"/>
<symbol name="P" address="BITS:d0"/>
<symbol name="UD" address="BITS:d1"/>
<symbol name="OV" address="BITS:d2"/>
<symbol name="RS0" address="BITS:d3"/>
<symbol name="RS1" address="BITS:d4"/>
<symbol name="F0" address="BITS:d5"/>
<symbol name="AC" address="BITS:d6"/>
<symbol name="C" address="BITS:d7"/>
<symbol name="CCF.0" address="BITS:d8"/>
<symbol name="CCF.1" address="BITS:d9"/>
<symbol name="CCF.2" address="BITS:da"/>
<symbol name="CCF.3" address="BITS:db"/>
<symbol name="CCF.4" address="BITS:dc"/>
<symbol name="CCON.5" address="BITS:dd"/>
<symbol name="CR" address="BITS:de"/>
<symbol name="CF" address="BITS:df"/>
<symbol name="ACC.0" address="BITS:e0"/>
<symbol name="ACC.1" address="BITS:e1"/>
<symbol name="ACC.2" address="BITS:e2"/>
<symbol name="ACC.3" address="BITS:e3"/>
<symbol name="ACC.4" address="BITS:e4"/>
<symbol name="ACC.5" address="BITS:e5"/>
<symbol name="ACC.6" address="BITS:e6"/>
<symbol name="ACC.7" address="BITS:e7"/>
<symbol name="HIFLG.0" address="BITS:e8"/>
<symbol name="HIFLG.1" address="BITS:e9"/>
<symbol name="HIFLG.2" address="BITS:ea"/>
<symbol name="HIFLG.3" address="BITS:eb"/>
<symbol name="HIFLG.4" address="BITS:ec"/>
<symbol name="HIFLG.5" address="BITS:ed"/>
<symbol name="HIFLG.6" address="BITS:ee"/>
<symbol name="HIFLG.7" address="BITS:ef"/>
<symbol name="B.0" address="BITS:f0"/>
<symbol name="B.1" address="BITS:f1"/>
<symbol name="B.2" address="BITS:f2"/>
<symbol name="B.3" address="BITS:f3"/>
<symbol name="B.4" address="BITS:f4"/>
<symbol name="B.5" address="BITS:f5"/>
<symbol name="B.6" address="BITS:f6"/>
<symbol name="B.7" address="BITS:f7"/>
<symbol name="F8.0" address="BITS:f8"/>
<symbol name="F8.1" address="BITS:f9"/>
<symbol name="F8.2" address="BITS:fa"/>
<symbol name="F8.3" address="BITS:fb"/>
<symbol name="F8.4" address="BITS:fc"/>
<symbol name="F8.5" address="BITS:fd"/>
<symbol name="F8.6" address="BITS:fe"/>
<symbol name="F8.7" address="BITS:ff"/>
</default_symbols>
<default_memory_blocks>
<memory_block name="REG_BANK_1" start_address="RAM:7f0000" length="0x8" initialized="false"/>
<memory_block name="REG_BANK_2" start_address="RAM:7f0008" length="0x8" initialized="false"/>
<memory_block name="REG_BANK_3" start_address="RAM:7f0010" length="0x8" initialized="false"/>
<memory_block name="REG_BANK_4" start_address="RAM:7f0018" length="0x8" initialized="false"/>
<memory_block name="INTMEM" start_address="RAM:7f0020" length="0xe0" initialized="false"/>
<memory_block name="EXTMEM" start_address="RAM:0" length="0x1000" initialized="false"/>
<memory_block name="BITS" start_address="BITS:00" bit_mapped_address="RAM:7f0020" length="0x80"/>
<memory_block name="SFR" start_address="SFR:80" length="0x80" initialized="false"/>
<memory_block name="ESFR" start_address="ESFR:80" length="0x80" initialized="false"/>
<memory_block name="EBITS" start_address="EBITS:00" bit_mapped_address="RAM:7f0020" length="0x80"/>
<!-- BUG: SFR-BITS do not map properly since only every 8th SFR register is mapped (e.g., 0x80, 0x88, 0x90 ... 0xF0, 0xF8) -->
<memory_block name="SFR-BITS" start_address="BITS:80" bit_mapped_address="SFR:80" length="0x80"/>
<memory_block name="ESFR-BITS" start_address="EBITS:80" bit_mapped_address="ESFR:80" length="0x80"/>
</default_memory_blocks>
</processor_spec>
@@ -0,0 +1,332 @@
# Extended mx51 instructions live here, so as to avoid further
# complicating the main 8051 file.
# All have 0xa5 as prefix, so subtract one
define token TwoByteOp (8)
b2op = (0,7)
;
define token ThreeByteOp (16)
b3op = (8,15)
;
define token FourByteOp (24)
b4op = (16,23)
;
define token EcallDispTok (24)
imm24 = (0,23)
;
####################
# Note that PRi is used in little endian format, as R3 is the MSB
attach variables PRi_revend [ R1R2R3 R5R6R7 ];
@define ENDIANSWAPFUNC ""
@if defined(ENDIANSWAPFUNC)
define pcodeop endian_swap;
PRi: PRi_revend is PRi_revend { tmp:3 = endian_swap(PRi_revend); export tmp; }
@else
PRi: PRi_revend is PRi_sel=0 & PRi_revend { tmp:3 = (zext(R3) << 16) | (zext(R2) << 8) | zext(R1); export tmp; }
PRi: PRi_revend is PRi_sel=1 & PRi_revend { tmp:3 = (zext(R7) << 16) | (zext(R6) << 8) | zext(R5); export tmp; }
@endif
####################
@ifdef OMIT_RETADDR
macro push24(val) { val = val; }
macro pop24(val) { val = val; }
@else
# stack grows up.
macro push24(val) {
ptr:3 = zext(SP) + 1 + $(STACKBASE);
*[RAM]:3 ptr = val;
SP = SP + 2;
}
macro pop24(val) {
ptr:3 = zext(SP - 2) + $(STACKBASE);
val = *[RAM]:3 ptr;
SP = SP - 3;
}
@endif
####################
eptrReg: EPTR is EPTR { export EPTR; }
APlusEptr: "@"Areg"+"eptrReg is Areg & eptrReg { tmp:3 = EPTR + zext(ACC); export tmp; }
ecallImmAddr: imm24 is imm24 { export *:1 imm24; }
add_with_pr_const: emov_delta is emov_delta { tmp:1 = emov_delta; export tmp; }
add_with_pr_const: "4" is emov_delta = 0 { tmp:1 = 4; export tmp; }
EDirect: mainreg is bank=0 & mainreg { tmp:3 = mainreg + 0x7f0000; export *[RAM]:1 tmp; }
EDirect: direct is bank=1 & direct { export *[ESFR]:1 direct; }
EDirect: EPL is bank=1 & direct=0xfc & EPL { export EPL; }
EDirect: EPM is bank=1 & direct=0xfd & EPM { export EPM; }
EDirect: EPH is bank=1 & direct=0xfe & EPH { export EPH; }
EDirect2: mainreg2 is bank2=0 & mainreg2 { tmp:3 = mainreg2 + 0x7f0000; export *[RAM]:1 tmp; }
EDirect2: direct2 is bank2=1 & direct2 { export *[ESFR]:1 direct2; }
EDirect2: EPL is bank2=1 & direct2=0xfc & EPL { export EPL; }
EDirect2: EPM is bank2=1 & direct2=0xfd & EPM { export EPM; }
EDirect2: EPH is bank2=1 & direct2=0xfe & EPH { export EPH; }
# Continuing with pattern via copying from stock 8051 sleighspec.
# Note that there is a known bug with the Bit addressing of the SFR.
EBitAddr: bitaddr is bitbank=1 & sfrbyte & sfrbit [ bitaddr =(sfrbyte << 3)+sfrbit; ] { export *[EBITS]:1 bitaddr; }
EBitAddr: bitaddr is bitbank=0 & lowbyte & sfrbit [ bitaddr =(lowbyte << 3)+sfrbit; ] { export *[EBITS]:1 bitaddr; }
EBitAddr2: "/"bitaddr is bitbank=1 & sfrbyte & sfrbit [ bitaddr =(sfrbyte << 3)+sfrbit; ] { export *[EBITS]:1 bitaddr; }
EBitAddr2: "/"bitaddr is bitbank=0 & lowbyte & sfrbit [ bitaddr =(lowbyte << 3)+sfrbit; ] { export *[EBITS]:1 bitaddr; }
EBitByteAddr: byteaddr is bitbank=1 & sfrbyte & sfrbit [ byteaddr =(sfrbyte << 3); ] { export *[ESFR]:1 byteaddr; }
EBitByteAddr: byteaddr is bitbank=0 & lowbyte & sfrbit [ byteaddr = lowbyte + 0x20; ] { tmp:3 = byteaddr + 0x7f0000; export *[RAM]:1 tmp; }
####################
:inc EDirect is opfull=0xa5; ophi=0 & oplo=5; EDirect {
EDirect = EDirect + 1;
}
:dec EDirect is opfull=0xa5; opfull=0x15; EDirect {
EDirect = EDirect - 1;
}
:add Areg,EDirect is opfull=0xa5; opfull=0x25 & Areg; EDirect {
addflags(ACC,EDirect); ACC = ACC + EDirect; resultflags(ACC);
}
:addc Areg,EDirect is opfull=0xa5; opfull=0x35 & Areg; EDirect {
tmp:1 =$(CY)+ EDirect; addflags(ACC,tmp); ACC = ACC + tmp; resultflags(ACC);
}
:orl Areg,EDirect is opfull=0xa5; opfull=0x45 & Areg; EDirect {
ACC = ACC | EDirect;
}
:anl Areg,EDirect is opfull=0xa5; opfull=0x55 & Areg; EDirect {
ACC = ACC & EDirect; resultflags(ACC);
}
:xrl Areg,EDirect is opfull=0xa5; opfull=0x65 & Areg; EDirect {
ACC = ACC ^ EDirect;
}
:subb Areg,EDirect is opfull=0xa5; opfull=0x95 & Areg; EDirect {
tmp:1 = EDirect+$(CY); subflags(ACC,tmp); ACC = ACC - tmp;
}
:xch Areg,EDirect is opfull=0xa5; opfull=0xc5 & Areg; EDirect {
tmp:1 = ACC; ACC = EDirect; EDirect = tmp;
}
:mov Areg,EDirect is opfull=0xa5; opfull=0xe5 & Areg; EDirect {
ACC = EDirect;
}
:mov EDirect,Areg is opfull=0xa5; opfull=0xf5 & Areg; EDirect {
EDirect = ACC;
}
:mov EDirect,rn is opfull=0xa5; ophi=0x8 & rnfill=1 & rn; EDirect {
EDirect = rn;
}
:mov rn,EDirect is opfull=0xa5; ophi=0xa & rnfill=1 & rn; EDirect {
rn = EDirect;
}
:mov EDirect2,EDirect is opfull=0xa5; ophi=8 & oplo=5; EDirect; EDirect2 {
EDirect2 = EDirect;
}
:mov EDirect,Data is opfull=0xa5; ophi=7 & oplo=5; EDirect; Data {
EDirect = Data;
}
:mov EDirect,Ri is opfull=0xa5; ophi=8 & rifill=3 & Ri; EDirect {
EDirect = Ri;
}
:mov Ri,EDirect is opfull=0xa5; ophi=10 & rifill=3 & Ri; EDirect {
Ri = EDirect;
}
:orl EDirect,Areg is opfull=0xa5; ophi=4 & oplo=2 & Areg; EDirect {
EDirect = EDirect | ACC;
}
:anl EDirect,Areg is opfull=0xa5; ophi=5 & oplo=2 & Areg; EDirect {
tmp:1 = EDirect & ACC; EDirect = tmp; resultflags(tmp);
}
:xrl EDirect,Areg is opfull=0xa5; ophi=6 & oplo=2 & Areg; EDirect {
EDirect = EDirect ^ ACC;
}
:xrl EDirect,Data is opfull=0xa5; ophi=6 & oplo=3; EDirect; Data {
EDirect = EDirect ^ Data;
}
:anl EDirect,Data is opfull=0xa5; ophi=5 & oplo=3; EDirect; Data {
tmp:1 = EDirect & Data; EDirect = tmp; resultflags(tmp);
}
:orl EDirect,Data is opfull=0xa5; ophi=4 & oplo=3 & Areg; EDirect; Data {
EDirect = EDirect | Data;
}
:push EDirect is opfull=0xa5; opfull=0xc0; EDirect {
push8(EDirect);
}
:pop EDirect is opfull=0xa5; opfull=0xd0; EDirect {
pop8(EDirect);
}
:cjne Areg,EDirect,Rel8 is opfull=0xa5; ophi=11 & oplo=5 & Areg; EDirect; Rel8 {
compflags(ACC,EDirect); if (ACC!=EDirect) goto Rel8;
}
:djnz EDirect,Rel8 is opfull=0xa5; ophi=13 & oplo=5; EDirect; Rel8 {
EDirect = EDirect - 1;
if (EDirect!=0) goto Rel8;
}
# EPTR operations
:ejmp ecallImmAddr is opfull=0xa5; opfull=0x02; ecallImmAddr {
goto ecallImmAddr;
}
:ecall ecallImmAddr is opfull=0xa5; opfull=0x12; ecallImmAddr {
ret:3 = inst_next; push24(ret); call ecallImmAddr;
}
:mov eptrReg,ecallImmAddr is opfull=0xa5; opfull=0x90; ecallImmAddr & eptrReg & imm24 {
EPTR = imm24;
}
:eret is opfull=0xa5; opfull=0x22 {
pc:3 = 0; pop24(pc); return[pc];
}
:jmp APlusEptr is opfull=0xa5; opfull=0x73 & APlusEptr {
# this is correct, but causes disassembler problems
# goto APlusEptr;
# added additional indirection to stop disassembler problems.
goto [APlusEptr];
}
:movx Areg",@"eptrReg is opfull=0xa5; opfull=0xe0 & Areg & eptrReg {
ACC = *:1 EPTR;
}
:movx "@"eptrReg,Areg is opfull=0xa5; opfull=0xf0 & Areg & eptrReg {
*:1 EPTR = ACC;
}
:movc Areg,APlusEptr is opfull=0xa5; opfull=0x93 & Areg & APlusEptr {
ACC = *:1 APlusEptr;
}
:inc EPTR is opfull=0xa5; opfull=0xa3 & EPTR {
EPTR = EPTR + 1;
}
# PRi operations
:emov Areg",@"PRi"+"emov_delta is opfull=0xa5; ophi=4 & PRi & emov_delta & Areg {
tmp:3 = zext(PRi) + emov_delta;
ACC = *:1 tmp;
}
:emov "@"PRi"+"emov_delta,Areg is opfull=0xa5; ophi=5 & PRi & emov_delta & Areg {
tmp:3 = PRi + emov_delta;
*:1 tmp = ACC;
}
:add PRi_revend,add_with_pr_const is opfull=0xa5; ophi=6 & PRi_revend & PRi & add_with_pr_const {
x:3 = zext(add_with_pr_const);
tmp:3 = PRi + x;
@if defined(ENDIANSWAPFUNC)
y:3 = endian_swap(tmp);
@else
y:3 = (tmp << 16) | (tmp & 0x00ff00) | zext(tmp >> 16);
@endif
PRi_revend = y;
}
# bit operations
:anl CY,EBitAddr is opfull=0xa5; CY & ophi=8 & oplo=2; EBitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & EBitByteAddr {tmp:1 = EBitByteAddr; $(CY)=$(CY)& ((tmp>>sfrbit)&1); resultflags(tmp); }
:anl CY,EBitAddr2 is opfull=0xa5; CY & ophi=11 & oplo=0; EBitAddr2 & bitaddr57=7 & sfrbit3=0 & sfrbit & EBitByteAddr {tmp:1 = EBitByteAddr; $(CY)=$(CY)& (~((tmp>>sfrbit)&1)); }
@if BIT_OPS == "BIT_ADDRS"
:anl CY,EBitAddr is opfull=0xa5; CY & ophi=8 & oplo=2; EBitAddr & sfrbit & EBitByteAddr {$(CY)=$(CY)& EBitAddr; }
:anl CY,EBitAddr2 is opfull=0xa5; CY & ophi=11 & oplo=0; EBitAddr2 & sfrbit & EBitByteAddr {$(CY)=$(CY)& ~EBitAddr2; }
@elif BIT_OPS == "PCODEOPS"
:anl CY,EBitAddr is opfull=0xa5; CY & ophi=8 & oplo=2; EBitAddr & sfrbit & EBitByteAddr {$(CY)=$(CY)& get(EBitAddr, EBitByteAddr); }
:anl CY,EBitAddr2 is opfull=0xa5; CY & ophi=11 & oplo=0; EBitAddr2 & sfrbit & EBitByteAddr {$(CY)=$(CY)& (get(EBitAddr2, EBitByteAddr)^1); }
@elif BIT_OPS == "SHIFTS"
:anl CY,EBitAddr is opfull=0xa5; CY & ophi=8 & oplo=2; EBitAddr & sfrbit & EBitByteAddr {$(CY)=$(CY)& ((EBitByteAddr>>sfrbit)&1); }
:anl CY,EBitAddr2 is opfull=0xa5; CY & ophi=11 & oplo=0; EBitAddr2 & sfrbit & EBitByteAddr {$(CY)=$(CY)& (~((EBitByteAddr>>sfrbit)&1)); }
@endif
:clr EBitAddr is opfull=0xa5; ophi=12 & oplo=2; EBitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & EBitByteAddr { tmp:1 = ~(1<<sfrbit); EBitByteAddr = EBitByteAddr & tmp; }
@if BIT_OPS == "BIT_ADDRS"
:clr EBitAddr is opfull=0xa5; ophi=12 & oplo=2; EBitAddr & sfrbit & EBitByteAddr { EBitAddr = 0; }
@elif BIT_OPS == "PCODEOPS"
:clr EBitAddr is opfull=0xa5; ophi=12 & oplo=2; EBitAddr & sfrbit & EBitByteAddr { EBitByteAddr = clr(EBitAddr, EBitByteAddr); }
#:CLR PortBit is opfull=0xa5; ophi=12 & oplo=2; PortBit & sfrbit & EBitByteAddr { outp(PortBit, 0:1, EBitByteAddr); }
@elif BIT_OPS == "SHIFTS"
:clr EBitAddr is opfull=0xa5; ophi=12 & oplo=2; EBitAddr & sfrbit & EBitByteAddr { tmp:1 = ~(1<<sfrbit); EBitByteAddr = EBitByteAddr & tmp; }
@endif
:cpl EBitAddr is opfull=0xa5; ophi=11 & oplo=2; EBitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & EBitByteAddr { tmp:1 = (1<<sfrbit); EBitByteAddr = EBitByteAddr ^ tmp; }
@if BIT_OPS == "BIT_ADDRS"
:cpl EBitAddr is opfull=0xa5; ophi=11 & oplo=2; EBitAddr & sfrbit & EBitByteAddr { EBitAddr = EBitAddr ^ 1; }
@elif BIT_OPS == "PCODEOPS"
:cpl EBitAddr is opfull=0xa5; ophi=11 & oplo=2; EBitAddr & sfrbit & EBitByteAddr { tmp:1 = get(EBitAddr, EBitByteAddr) ^ 1; EBitByteAddr = set_bit_value(EBitAddr, tmp, EBitByteAddr); }
@elif BIT_OPS == "SHIFTS"
:cpl EBitAddr is opfull=0xa5; ophi=11 & oplo=2; EBitAddr & sfrbit & EBitByteAddr { tmp:1 = (1<<sfrbit); EBitByteAddr = EBitByteAddr ^ tmp; }
@endif
:jb EBitAddr,Rel8 is opfull=0xa5; ophi=2 & oplo=0; EBitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & EBitByteAddr; Rel8 { if (((EBitByteAddr>>sfrbit)&1) == 1:1) goto Rel8; }
:jbc EBitAddr,Rel8 is opfull=0xa5; ophi=1 & oplo=0; EBitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & EBitByteAddr; Rel8 { tmp:1 = 1<<sfrbit; if ((EBitByteAddr & tmp)==0) goto inst_next; EBitByteAddr = EBitByteAddr & ~tmp; goto Rel8; }
@if BIT_OPS == "BIT_ADDRS"
:jb EBitAddr,Rel8 is opfull=0xa5; ophi=2 & oplo=0; EBitAddr & sfrbit & EBitByteAddr; Rel8 { if (EBitAddr == 1:1) goto Rel8; }
:jbc EBitAddr,Rel8 is opfull=0xa5; ophi=1 & oplo=0; EBitAddr & sfrbit & EBitByteAddr; Rel8 { if (EBitAddr == 0:1) goto inst_next; EBitAddr = 0; goto Rel8; }
@elif BIT_OPS == "PCODEOPS"
:jb EBitAddr,Rel8 is opfull=0xa5; ophi=2 & oplo=0; EBitAddr & sfrbit & EBitByteAddr; Rel8 { if (get(EBitAddr, EBitByteAddr)==1:1) goto Rel8; }
:jbc EBitAddr,Rel8 is opfull=0xa5; ophi=1 & oplo=0; EBitAddr & sfrbit & EBitByteAddr; Rel8 { tmp:1 = get(EBitAddr, EBitByteAddr); if (tmp==0) goto inst_next; EBitByteAddr = clr(EBitAddr, EBitByteAddr); goto Rel8; }
@elif BIT_OPS == "SHIFTS"
:jb EBitAddr,Rel8 is opfull=0xa5; ophi=2 & oplo=0; EBitAddr & sfrbit & EBitByteAddr; Rel8 { if (((EBitByteAddr>>sfrbit)&1) == 1:1) goto Rel8; }
:jbc EBitAddr,Rel8 is opfull=0xa5; ophi=1 & oplo=0; EBitAddr & sfrbit & EBitByteAddr; Rel8 { tmp:1 = 1<<sfrbit; if ((EBitByteAddr & tmp)==0) goto inst_next; EBitByteAddr = EBitByteAddr & ~tmp; goto Rel8; }
@endif
:jnb EBitAddr,Rel8 is opfull=0xa5; ophi=3 & oplo=0; EBitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & EBitByteAddr; Rel8 { if (((EBitByteAddr>>sfrbit)&1)==0:1) goto Rel8; }
@if BIT_OPS == "BIT_ADDRS"
:jnb EBitAddr,Rel8 is opfull=0xa5; ophi=3 & oplo=0; EBitAddr & sfrbit & EBitByteAddr; Rel8 { if (EBitAddr == 0:1) goto Rel8; }
@elif BIT_OPS == "PCODEOPS"
:jnb EBitAddr,Rel8 is opfull=0xa5; ophi=3 & oplo=0; EBitAddr & sfrbit & EBitByteAddr; Rel8 { if (get(EBitAddr, EBitByteAddr)==0:1) goto Rel8; }
@elif BIT_OPS == "SHIFTS"
:jnb EBitAddr,Rel8 is opfull=0xa5; ophi=3 & oplo=0; EBitAddr & sfrbit & EBitByteAddr; Rel8 { if (((EBitByteAddr>>sfrbit)&1)==0:1) goto Rel8; }
@endif
:mov CY,EBitAddr is opfull=0xa5; CY & ophi=10 & oplo=2; EBitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & EBitByteAddr {$(CY)= (EBitByteAddr>>sfrbit)&1; }
:mov EBitAddr,CY is opfull=0xa5; CY & ophi=9 & oplo=2; EBitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & EBitByteAddr { EBitByteAddr = EBitByteAddr & (~(1<<sfrbit)); EBitByteAddr = EBitByteAddr | ($(CY)<<sfrbit); }
@if BIT_OPS == "BIT_ADDRS"
:mov CY,EBitAddr is opfull=0xa5; CY & ophi=10 & oplo=2; EBitAddr & sfrbit & EBitByteAddr {$(CY)= EBitAddr; }
:mov EBitAddr,CY is opfull=0xa5; CY & ophi=9 & oplo=2; EBitAddr & sfrbit & EBitByteAddr { EBitAddr = $(CY); }
@elif BIT_OPS == "PCODEOPS"
:mov CY,EBitAddr is opfull=0xa5; CY & ophi=10 & oplo=2; EBitAddr & sfrbit & EBitByteAddr {$(CY) = get(EBitAddr, EBitByteAddr); }
:mov EBitAddr,CY is opfull=0xa5; CY & ophi=9 & oplo=2; EBitAddr & sfrbit & EBitByteAddr { EBitByteAddr = set_bit_value(EBitAddr, $(CY), EBitByteAddr); }
@elif BIT_OPS == "SHIFTS"
:mov CY,EBitAddr is opfull=0xa5; CY & ophi=10 & oplo=2; EBitAddr & sfrbit & EBitByteAddr{$(CY)= (EBitByteAddr>>sfrbit)&1; }
:mov EBitAddr,CY is opfull=0xa5; CY & ophi=9 & oplo=2; EBitAddr & sfrbit & EBitByteAddr { EBitByteAddr = EBitByteAddr & (~(1<<sfrbit)); EBitByteAddr = EBitByteAddr | ($(CY)<<sfrbit); }
@endif
:orl CY,EBitAddr is opfull=0xa5; CY & ophi=7 & oplo=2; EBitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & EBitByteAddr {$(CY)=$(CY)| ((EBitByteAddr>>sfrbit)&1); }
:orl CY,EBitAddr2 is opfull=0xa5; CY & ophi=10 & oplo=0; EBitAddr2 & bitaddr57=7 & sfrbit3=0 & sfrbit & EBitByteAddr {$(CY)=$(CY)| (((EBitByteAddr>>sfrbit)&1)^1); }
@if BIT_OPS == "BIT_ADDRS"
:orl CY,EBitAddr is opfull=0xa5; CY & ophi=7 & oplo=2; EBitAddr & sfrbit & EBitByteAddr {$(CY)=$(CY)| EBitAddr; }
:orl CY,EBitAddr2 is opfull=0xa5; CY & ophi=10 & oplo=0; EBitAddr2 & sfrbit & EBitByteAddr {$(CY)=$(CY)| (EBitAddr2^1); }
@elif BIT_OPS == "PCODEOPS"
:orl CY,EBitAddr is opfull=0xa5; CY & ophi=7 & oplo=2; EBitAddr & sfrbit & EBitByteAddr {$(CY)=$(CY)| get(EBitAddr, EBitByteAddr); }
:orl CY,EBitAddr2 is opfull=0xa5; CY & ophi=10 & oplo=0; EBitAddr2 & sfrbit & EBitByteAddr {$(CY)=$(CY)| (get(EBitAddr2, EBitByteAddr)^1); }
@elif BIT_OPS == "SHIFTS"
:orl CY,EBitAddr is opfull=0xa5; CY & ophi=7 & oplo=2; EBitAddr & sfrbit & EBitByteAddr {$(CY)=$(CY)| ((EBitByteAddr>>sfrbit)&1); }
:orl CY,EBitAddr2 is opfull=0xa5; CY & ophi=10 & oplo=0; EBitAddr2 & sfrbit & EBitByteAddr {$(CY)=$(CY)| (((EBitByteAddr>>sfrbit)&1)^1); }
@endif
:setb EBitAddr is opfull=0xa5; ophi=13 & oplo=2; EBitAddr & bitaddr57=7 & sfrbit3=0 & sfrbit & EBitByteAddr { EBitByteAddr = EBitByteAddr | (1<<sfrbit); }
@if BIT_OPS == "BIT_ADDRS"
:setb EBitAddr is opfull=0xa5; ophi=13 & oplo=2; EBitAddr & sfrbit & EBitByteAddr { EBitAddr = 1; }
@elif BIT_OPS == "PCODEOPS"
:setb EBitAddr is opfull=0xa5; ophi=13 & oplo=2; EBitAddr & sfrbit & EBitByteAddr { EBitByteAddr = set(EBitAddr, EBitByteAddr); }
@elif BIT_OPS == "SHIFTS"
:setb EBitAddr is opfull=0xa5; ophi=13 & oplo=2; EBitAddr & sfrbit & EBitByteAddr { EBitByteAddr = EBitByteAddr | (1<<sfrbit); }
@endif
########################################################################
@if defined(INS_FUSION)
# Eventually, it is hoped that the decompiler will just handle these.
# In the meantime, lets try to rewrite so to help the decompiler out.
#
# Due to compiler optimizations, this can sometimes lead to bad results
# on 8051 derivatives. E.g, jumps to the middle of the fused instruction.
define token Fuse4ByteToken (32)
f4op1 = (24,31)
f4op1imm8 = (16,23)
f4op2 = (8,15)
f4op2imm8 = (0,7)
;
f4imm16: val is f4op1imm8 & f4op2imm8 [ val = (f4op2imm8 << 8) | f4op1imm8; ] { tmp:2 = val; export tmp; }
# Just do r7 r6 for now
:mov_fused R6R7,"#"f4imm16 is f4op1=0x7f & f4op2=0x7e & R6R7 & f4imm16 {
R6R7 = f4imm16;
}
@endif
@@ -0,0 +1,7 @@
@define MX51 ""
@define OMIT_RETADDR 1
@define DUAL_DPTR ""
@define DPS_REG_NUM 0xa2
@include "8051_main.sinc"
@include "mx51.sinc"
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<language version="1" endian="big">
<description>
<id>8051:BE:16:default</id>
<processor>8051</processor>
<variant>default</variant>
<size>16</size>
</description>
<compiler name="default" id="default" />
<compiler name="Archimedes" id="Archimedes" />
<spaces>
<space name="CODE" type="ram" size="2" default="yes" />
<space name="INTMEM" type="ram" size="1" />
<space name="BITS" type="ram" size="1" />
<space name="SFR" type="ram" size="1" />
<space name="EXTMEM" type="ram" size="2" />
<space name="register" type="register" size="1" />
</spaces>
<registers>
<register name="R0" offset="0x0" bitsize="8" />
<register name="R1" offset="0x1" bitsize="8" />
<register name="R2" offset="0x2" bitsize="8" />
<register name="R3" offset="0x3" bitsize="8" />
<register name="R4" offset="0x4" bitsize="8" />
<register name="R5" offset="0x5" bitsize="8" />
<register name="R6" offset="0x6" bitsize="8" />
<register name="R7" offset="0x7" bitsize="8" />
<register name="R3R2R1" offset="0x1" bitsize="24" />
<register name="R2R1" offset="0x1" bitsize="16" />
<register name="R5R4" offset="0x4" bitsize="16" />
<register name="R7R6" offset="0x6" bitsize="16" />
<register name="R7R6R5R4" offset="0x4" bitsize="32" />
<register name="ACC" offset="0xe0" bitsize="8" />
<register name="B" offset="0xf0" bitsize="8" />
<register name="C" offset="0x22" bitsize="8" />
<register name="DPTR" offset="0x82" bitsize="16" />
<register name="DPH" offset="0x82" bitsize="8" />
<register name="DPL" offset="0x83" bitsize="8" />
<register name="PC" offset="0x20" bitsize="16" />
<register name="SP" offset="0x81" bitsize="8" />
<register name="PSW" address="SFR:d0" bitsize="8" />
</registers>
</language>
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<language_translation>
<from_language version="1">8051:BE:16:default</from_language>
<to_language version="2">8051:BE:16:default</to_language>
<map_compiler_spec from="default" to="default" />
<map_compiler_spec from="Archimedes" to="Archimedes" />
</language_translation>
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<compiler_spec>
<global>
<range space="ram"/>
</global>
<stackpointer register="SP" space="ram" growth="negative"/>
<default_proto>
<prototype name="__stdcall" extrapop="2" stackshift="2">
<input>
<pentry minsize="1" maxsize="1">
<register name="A"/>
</pentry>
<pentry minsize="1" maxsize="1">
<register name="B"/>
</pentry>
</input>
<output>
<pentry minsize="1" maxsize="1">
<register name="A"/>
</pentry>
</output>
<unaffected>
<register name="SP"/>
</unaffected>
</prototype>
</default_proto>
</compiler_spec>
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<language_definitions>
<language processor="8085"
endian="little"
size="16"
variant="default"
version="1.0"
slafile="8085.sla"
processorspec="8085.pspec"
id="8085:LE:16:default">
<description>Intel 8085</description>
<compiler name="default" spec="8085.cspec" id="default"/>
</language>
</language_definitions>
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<processor_spec>
<programcounter register="PC"/>
<register_data>
<register name="CY_flag" group="Flags"/>
<register name="P_flag" group="Flags"/>
<register name="AC_flag" group="Flags"/>
<register name="Z_flag" group="Flags"/>
<register name="S_flag" group="Flags"/>
<register name="AF_" group="Alt"/>
<register name="BC_" group="Alt"/>
<register name="DE_" group="Alt"/>
<register name="HL_" group="Alt"/>
</register_data>
<default_symbols>
<symbol name="RST0" address="ram:0000" entry="true"/>
<symbol name="RST1" address="ram:0008" entry="false"/>
<symbol name="RST2" address="ram:0010" entry="false"/>
<symbol name="RST3" address="ram:0018" entry="false"/>
<symbol name="RST4" address="ram:0020" entry="false"/>
<symbol name="RST5" address="ram:0028" entry="false"/>
<symbol name="RST6" address="ram:0030" entry="false"/>
<symbol name="RST7" address="ram:0038" entry="false"/>
<symbol name="RST5.5" address="ram:002c" entry="false"/>
<symbol name="RST6.5" address="ram:0034" entry="false"/>
<symbol name="RST7.5" address="ram:003c" entry="false"/>
<symbol name="TRAP" address="ram:0024" entry="false"/>
</default_symbols>
</processor_spec>
@@ -0,0 +1,551 @@
# sleigh specification file for Intel 8085
define endian=little;
define alignment=1;
define space ram type=ram_space size=2 default;
define space io type=ram_space size=1;
define space register type=register_space size=1;
define register offset=0x00 size=1 [ F A C B E D L H ];
define register offset=0x00 size=2 [ AF BC DE HL ];
define register offset=0x10 size=1 [ A_ F_ B_ C_ D_ E_ H_ L_ ]; # Alternate registers
define register offset=0x10 size=2 [ AF_ BC_ DE_ HL_ ]; # Alternate registers
define register offset=0x20 size=2 [ PC SP ];
# Flag bits
# CY: Carry
# P: Parity/Overflow
# AC: Half Carry (Auxiliary flag)
# Z: Zero
# S: Sign
define register offset=0x30 size=1 [ S_flag Z_flag AC_flag P_flag CY_flag ];
define token opbyte (8)
op0_8 = (0,7)
op6_2 = (6,7)
dRegPair4_2 = (4,5)
pRegPair4_2 = (4,5)
sRegPair4_2 = (4,5)
qRegPair4_2 = (4,5)
rRegPair4_2 = (4,5)
reg3_3 = (3,5)
bits3_3 = (3,5)
bits0_4 = (0,3)
reg0_3 = (0,2)
bits0_3 = (0,2)
;
define token data8 (8)
imm8 = (0,7)
sign8 = (7,7)
simm8 = (0,7) signed
;
define token data16 (16)
imm16 = (0,15)
sign16 = (15,15)
simm16 = (0,15) signed
;
attach variables [ reg0_3 reg3_3 ] [ B C D E H L _ A ];
attach variables [ sRegPair4_2 dRegPair4_2 ] [ BC DE HL SP ];
attach variables [ qRegPair4_2 ] [ BC DE HL AF ];
################################################################
# Pseudo Instructions
################################################################
define pcodeop BCDadjust;
define pcodeop hasEvenParity;
define pcodeop disableMaskableInterrupts;
define pcodeop enableMaskableInterrupts;
define pcodeop readInterruptMask;
define pcodeop setInterruptMask;
################################################################
# Macros
################################################################
macro setResultFlags(result) {
Z_flag = (result == 0);
S_flag = (result s< 0);
}
macro setAddCarryFlags(op1,op2) {
CY_flag = (carry(op1,zext(CY_flag)) || carry(op2,op1 + zext(CY_flag)));
# P_flag = (scarry(op1,CY_flag) || scarry(op2,op1 + CY_flag));
# AC_flag = ??
}
macro setAddFlags(op1,op2) {
CY_flag = carry(op1,op2);
# P_flag = scarry(op1,op2);
# AC_flag = ??
}
macro setSubtractCarryFlags(op1,op2) {
local notC = ~CY_flag;
CY_flag = ((op1 < sext(notC)) || (op2 < (op1 - sext(notC))));
}
macro setSubtractFlags(op1,op2) {
CY_flag = (op1 < op2);
}
macro push16(val16) {
SP = SP - 2;
*:2 SP = val16;
}
macro pop16(ret16) {
ret16 = *:2 SP;
SP = SP + 2;
}
################################################################
Mem8: (imm16) is imm16 { export *:1 imm16; }
Mem16: (imm16) is imm16 { export *:2 imm16; }
Addr16: imm16 is imm16 { export *:1 imm16; }
RstAddr: loc is bits3_3 [ loc = bits3_3 << 3; ] { export *:1 loc; }
IOAddr8: (imm8) is imm8 { export *[io]:1 imm8; }
cc: "NZ" is bits3_3=0x0 { c:1 = (Z_flag == 0); export c; }
cc: "Z" is bits3_3=0x1 { export Z_flag; }
cc: "NC" is bits3_3=0x2 { c:1 = (CY_flag == 0); export c; }
cc: "C" is bits3_3=0x3 { export CY_flag; }
cc: "PO" is bits3_3=0x4 { c:1 = (P_flag == 0); export c; }
cc: "PE" is bits3_3=0x5 { export P_flag; }
cc: "P" is bits3_3=0x6 { c:1 = (S_flag == 0); export c; }
cc: "M" is bits3_3=0x7 { export S_flag; }
################################################################
:MOV reg3_3,reg0_3 is op6_2=0x1 & reg3_3 & reg0_3 {
reg3_3 = reg0_3;
}
:MVI reg3_3,imm8 is op6_2=0x0 & reg3_3 & bits0_3=0x6; imm8 {
reg3_3 = imm8;
}
:MOV reg3_3,(HL) is op6_2=0x1 & reg3_3 & bits0_3=0x6 & HL {
ptr:2 = HL;
reg3_3 = *:1 ptr;
}
:MOV (HL),reg0_3 is op6_2=0x1 & bits3_3=0x6 & reg0_3 & HL {
ptr:2 = HL;
*:1 ptr = reg0_3;
}
:MVI (HL),imm8 is op0_8=0x36 & HL; imm8 {
ptr:2 = HL;
*:1 ptr = imm8;
}
:LDAX (BC) is op0_8=0x0a & BC {
ptr:2 = BC;
A = *:1 ptr;
}
:LDAX (DE) is op0_8=0x1a & DE {
ptr:2 = DE;
A = *:1 ptr;
}
:LDA Mem8 is op0_8=0x3a; Mem8 {
A = Mem8;
}
:STAX (BC) is op0_8=0x2 & BC {
ptr:2 = BC;
*:1 ptr = A;
}
:STAX (DE) is op0_8=0x12 & DE {
ptr:2 = DE;
*:1 ptr = A;
}
:STA Mem8 is op0_8=0x32; Mem8 {
Mem8 = A;
}
:LXI dRegPair4_2,imm16 is op6_2=0x0 & dRegPair4_2 & bits0_4=0x1; imm16 {
dRegPair4_2 = imm16;
}
:LHLD Mem16 is op0_8=0x2a; Mem16 {
HL = Mem16;
}
:SHLD Mem16 is op0_8=0x22; Mem16 {
Mem16 = HL;
}
:SPHL is op0_8=0xf9 {
SP = HL;
}
:PUSH qRegPair4_2 is op6_2=0x3 & qRegPair4_2 & bits0_4=0x5 {
push16(qRegPair4_2);
}
:POP qRegPair4_2 is op6_2=0x3 & qRegPair4_2 & bits0_4=0x1 {
pop16(qRegPair4_2);
}
:XCHG is op0_8=0xeb {
tmp:2 = DE;
DE = HL;
HL = tmp;
}
:XTHL is op0_8=0xe3 {
tmp:2 = *:2 SP;
*:2 SP = HL;
HL = tmp;
}
:ADD reg0_3 is op6_2=0x2 & bits3_3=0x0 & reg0_3 {
setAddFlags(A,reg0_3);
A = A + reg0_3;
setResultFlags(A);
}
:ADI imm8 is op0_8=0xc6; imm8 {
setAddFlags(A,imm8);
A = A + imm8;
setResultFlags(A);
}
:ADD (HL) is op0_8=0x86 & HL {
val:1 = *:1 HL;
setAddFlags(A,val);
A = A + val;
setResultFlags(A);
}
:ADC reg0_3 is op6_2=0x2 & bits3_3=0x1 & reg0_3 {
setAddCarryFlags(A,reg0_3);
A = A + reg0_3 + CY_flag;
setResultFlags(A);
}
:ACI imm8 is op0_8=0xce; imm8 {
setAddCarryFlags(A,imm8);
A = A + imm8 + CY_flag;
setResultFlags(A);
}
:ADC (HL) is op0_8=0x8e & HL {
val:1 = *:1 HL;
setAddCarryFlags(A,val);
A = A + val + CY_flag;
setResultFlags(A);
}
:SUB reg0_3 is op6_2=0x2 & bits3_3=0x2 & reg0_3 {
setSubtractFlags(A,reg0_3);
A = A - reg0_3;
setResultFlags(A);
}
:SUI imm8 is op0_8=0xd6; imm8 {
setSubtractFlags(A,imm8);
A = A - imm8;
setResultFlags(A);
}
:SUB (HL) is op0_8=0x96 & HL {
val:1 = *:1 HL;
setSubtractFlags(A,val);
A = A - val;
setResultFlags(A);
}
:SBB reg0_3 is op6_2=0x2 & bits3_3=0x3 & reg0_3 {
setSubtractCarryFlags(A,reg0_3);
A = A - reg0_3 - CY_flag;
setResultFlags(A);
}
:SBI imm8 is op0_8=0xde; imm8 {
setSubtractCarryFlags(A,imm8);
A = A - imm8 - CY_flag;
setResultFlags(A);
}
:SBB (HL) is op0_8=0x9e & HL {
val:1 = *:1 HL;
setSubtractCarryFlags(A,val);
A = A - val - CY_flag;
setResultFlags(A);
}
:ANA reg0_3 is op6_2=0x2 & bits3_3=0x4 & reg0_3 {
AC_flag = 1;
CY_flag = 0;
P_flag = 0;
A = A & reg0_3;
setResultFlags(A);
}
:ANI imm8 is op0_8=0xe6; imm8 {
AC_flag = 1;
CY_flag = 0;
P_flag = 0;
A = A & imm8;
setResultFlags(A);
}
:ANA (HL) is op0_8=0xa6 & HL {
AC_flag = 1;
CY_flag = 0;
P_flag = 0;
A = A & *:1 HL;
setResultFlags(A);
}
:ORA reg0_3 is op6_2=0x2 & bits3_3=0x6 & reg0_3 {
AC_flag = 0;
CY_flag = 0;
P_flag = 0;
A = A | reg0_3;
setResultFlags(A);
}
:ORI imm8 is op0_8=0xf6; imm8 {
AC_flag = 0;
CY_flag = 0;
P_flag = 0;
A = A | imm8;
setResultFlags(A);
}
:ORA (HL) is op0_8=0xb6 & HL {
AC_flag = 0;
CY_flag = 0;
P_flag = 0;
A = A | *:1 HL;
setResultFlags(A);
}
:XRA reg0_3 is op6_2=0x2 & bits3_3=0x5 & reg0_3 {
AC_flag = 0;
CY_flag = 0;
P_flag = 0;
A = A ^ reg0_3;
setResultFlags(A);
}
:XRA (HL) is op0_8=0xae & HL {
AC_flag = 0;
CY_flag = 0;
P_flag = 0;
A = A ^ *:1 HL;
setResultFlags(A);
}
:XRI imm8 is op0_8=0xee; imm8 {
AC_flag = 0;
CY_flag = 0;
P_flag = 0;
A = A ^ imm8;
setResultFlags(A);
}
:CMP reg0_3 is op6_2=0x2 & bits3_3=0x7 & reg0_3 {
setSubtractFlags(A,reg0_3);
cmp:1 = A - reg0_3;
setResultFlags(cmp);
}
:CPI imm8 is op0_8=0xfe; imm8 {
setSubtractFlags(A,imm8);
cmp:1 = A - imm8;
setResultFlags(cmp);
}
:CMP (HL) is op0_8=0xbe & HL {
val:1 = *:1 HL;
setSubtractFlags(A,val);
cmp:1 = A - val;
setResultFlags(cmp);
}
:INR reg3_3 is op6_2=0x0 & reg3_3 & bits0_3=0x4 {
P_flag = (reg3_3 == 0x7f);
reg3_3 = reg3_3 + 1;
setResultFlags(reg3_3);
}
:INR (HL) is op0_8=0x34 & HL {
val:1 = *:1 HL;
P_flag = (val == 0x7f);
val = val + 1;
*:1 HL = val;
setResultFlags(val);
}
:DCR reg3_3 is op6_2=0x0 & reg3_3 & bits0_3=0x5 {
P_flag = (reg3_3 == 0x80);
reg3_3 = reg3_3 - 1;
setResultFlags(reg3_3);
}
:DCR (HL) is op0_8=0x35 & HL {
val:1 = *:1 HL;
P_flag = (val == 0x80);
val = val - 1;
*:1 HL = val;
setResultFlags(val);
}
:DAA is op0_8=0x27 {
A = BCDadjust(A);
setResultFlags(A);
P_flag = hasEvenParity(A);
}
:CMA is op0_8=0x2f {
A = ~A;
}
:CMC is op0_8=0x3f {
CY_flag = !CY_flag;
}
:STC is op0_8=0x37 {
CY_flag = 1;
AC_flag = 0;
}
:NOP is op0_8=0x0 {
}
:HALT is op0_8=0x76 {
goto inst_start;
}
:DI is op0_8=0xf3 {
# IFF1 = 0;
# IFF2 = 0;
disableMaskableInterrupts();
}
:EI is op0_8=0xfb {
# IFF1 = 1;
# IFF2 = 1;
enableMaskableInterrupts();
}
:RIM is op0_8=0x20 {
A = readInterruptMask();
}
:SIM is op0_8=0x30 {
setInterruptMask(A);
}
:DAD HL,sRegPair4_2 is op6_2=0x0 & sRegPair4_2 & bits0_4=0x9 & HL {
setAddFlags(HL,sRegPair4_2);
HL = HL + sRegPair4_2;
}
:INX sRegPair4_2 is op6_2=0x0 & sRegPair4_2 & bits0_4=0x3 {
sRegPair4_2 = sRegPair4_2 + 1;
}
:DCX sRegPair4_2 is op6_2=0x0 & sRegPair4_2 & bits0_4=0xb {
sRegPair4_2 = sRegPair4_2 - 1;
}
:RLC is op0_8=0x07 {
CY_flag = (A >> 7);
A = (A << 1) | CY_flag;
AC_flag = 0;
}
:RAL is op0_8=0x17 {
nextC:1 = (A >> 7);
A = (A << 1) | CY_flag;
CY_flag = nextC;
AC_flag = 0;
}
:RRC is op0_8=0x0f {
CY_flag = (A & 1);
A = (A >> 1) | (CY_flag << 7);
AC_flag = 0;
}
:RAR is op0_8=0x1f {
nextC:1 = (A & 1);
A = (A >> 1) | (CY_flag << 7);
CY_flag = nextC;
AC_flag = 0;
}
:JMP Addr16 is op0_8=0xc3; Addr16 {
goto Addr16;
}
:J^cc Addr16 is op6_2=0x3 & cc & bits0_3=0x2; Addr16 {
if (cc) goto Addr16;
}
:PCHL is op0_8=0xe9 {
goto [HL];
}
:CALL Addr16 is op0_8=0xcd; Addr16 {
tmp:2 = inst_next;
push16(tmp);
call Addr16;
}
:C^cc Addr16 is op6_2=0x3 & cc & bits0_3=0x4; Addr16 {
if (!cc) goto inst_next;
tmp:2 = inst_next;
push16(tmp);
call Addr16;
}
:RET is op0_8=0xc9 {
tmp:2 = 0;
pop16(tmp);
return [tmp];
}
:R^cc is op6_2=0x3 & cc & bits0_3=0x0 {
if (!cc) goto inst_next;
tmp:2 = 0;
pop16(tmp);
return [tmp];
}
:RST RstAddr is op6_2=0x3 & RstAddr & bits0_3=0x7 {
tmp:2 = inst_next;
push16(tmp);
call RstAddr;
}
:IN IOAddr8 is op0_8=0xdb; IOAddr8 {
A = IOAddr8;
}
:OUT IOAddr8 is op0_8=0xd3; IOAddr8 {
IOAddr8 = A;
}
@@ -0,0 +1,205 @@
<?xml version="1.0" encoding="UTF-8"?>
<compiler_spec>
<data_organization>
<absolute_max_alignment value="0" />
<machine_alignment value="4" />
<default_alignment value="1" />
<default_pointer_alignment value="8" />
<pointer_size value="8" />
<wchar_size value="4" />
<short_size value="2" />
<integer_size value="4" />
<long_size value="8" />
<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"/>
<!-- The decompiler will treat registers in this range as global variables.
ie: tmp_ldWn, tmp_ldXn, tmp_stWn, tmp_stXn -->
<range space="register" first="0x3000" last="0x3fff"/>
</global>
<stackpointer register="sp" space="ram"/>
<funcptr align="4"/> <!-- Function pointers are word aligned and leastsig bit may encode otherstuff -->
<prefersplit style="inhalf">
<register name="q0"/>
<register name="q1"/>
<register name="q2"/>
<register name="q3"/>
<register name="q4"/>
<register name="q5"/>
<register name="q6"/>
<register name="q7"/>
<register name="q8"/>
<register name="q9"/>
<register name="q10"/>
<register name="q11"/>
<register name="q12"/>
<register name="q13"/>
<register name="q14"/>
<register name="q15"/>
<register name="q16"/>
<register name="q17"/>
<register name="q18"/>
<register name="q19"/>
<register name="q20"/>
<register name="q21"/>
<register name="q22"/>
<register name="q23"/>
<register name="q24"/>
<register name="q25"/>
<register name="q26"/>
<register name="q27"/>
<register name="q28"/>
<register name="q29"/>
<register name="q30"/>
</prefersplit>
<default_proto>
<prototype name="__cdecl" extrapop="0" stackshift="0">
<input>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d0"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d1"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d2"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d3"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d4"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d5"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d6"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d7"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x0"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x1"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x2"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x3"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x4"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x5"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x6"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x7"/>
</pentry>
<pentry minsize="1" maxsize="500" align="4">
<addr offset="0" space="stack"/>
</pentry>
</input>
<output>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d0"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x0"/>
</pentry>
<pentry minsize="9" maxsize="16" extension="zero">
<addr space="join" piece1="x1" piece2="x0"/>
</pentry>
</output>
<unaffected>
<register name="x19"/>
<register name="x20"/>
<register name="x21"/>
<register name="x22"/>
<register name="x23"/>
<register name="x24"/>
<register name="x25"/>
<register name="x26"/>
<register name="x27"/>
<register name="x28"/>
<register name="x29"/>
<register name="x30"/>
<register name="sp"/>
<!-- vectors -->
<register name="d8"/>
<register name="d9"/>
<register name="d10"/>
<register name="d11"/>
<register name="d12"/>
<register name="d13"/>
<register name="d14"/>
<register name="d15"/>
</unaffected>
<killedbycall>
<!-- x8: indirect result location register, which is not
reflected in the pentry list -->
<register name="x8"/>
<register name="x9"/>
<register name="x10"/>
<register name="x11"/>
<register name="x12"/>
<register name="x13"/>
<register name="x14"/>
<register name="x15"/>
<register name="x16"/>
<register name="x17"/>
<register name="x18"/>
<!-- vectors -->
<register name="d16"/>
<register name="d17"/>
<register name="d18"/>
<register name="d19"/>
<register name="d20"/>
<register name="d21"/>
<register name="d22"/>
<register name="d23"/>
<register name="d24"/>
<register name="d25"/>
<register name="d26"/>
<register name="d27"/>
<register name="d28"/>
<register name="d29"/>
<register name="d30"/>
<register name="d31"/>
</killedbycall>
</prototype>
</default_proto>
<callfixup name="PlaceHolderCallFixup"> <!-- This is here just to force call fixup and NoReturn fixup. Will be fixed in Ghidra V6.0 -->
<target name="___NotARealFunctionName___"/>
<pcode>
<body><![CDATA[
tmpptr:4 = 0;
]]></body>
</pcode>
</callfixup>
</compiler_spec>
@@ -0,0 +1,8 @@
<dwarf>
<register_mappings>
<register_mapping dwarf="0" ghidra="x0" auto_count="31"/> <!-- x0..x30 -->
<register_mapping dwarf="31" ghidra="xzr" stackpointer="true"/>
<register_mapping dwarf="64" ghidra="q0" auto_count="32"/> <!-- q0..q31 -->
</register_mappings>
<call_frame_cfa value="0"/>
</dwarf>
@@ -0,0 +1,64 @@
<?xml version="1.1" encoding="UTF-8"?>
<language_definitions>
<language processor="AARCH64"
endian="little"
size="64"
variant="v8A"
version="1.6"
slafile="AARCH64.sla"
processorspec="AARCH64.pspec"
manualindexfile="../manuals/AARCH64.idx"
id="AARCH64:LE:64:v8A">
<description>Generic ARM64 v8.5-A LE instructions, LE data, missing some 8.5 vector</description>
<compiler name="default" spec="AARCH64.cspec" id="default"/>
<compiler name="Visual Studio" spec="AARCH64_win.cspec" id="windows"/>
<external_name tool="gnu" name="aarch64"/>
<external_name tool="DWARF.register.mapping.file" name="AARCH64.dwarf"/>
</language>
<language processor="AARCH64"
endian="big"
instructionEndian="little"
size="64"
variant="v8A"
version="1.6"
slafile="AARCH64BE.sla"
processorspec="AARCH64.pspec"
manualindexfile="../manuals/AARCH64.idx"
id="AARCH64:BE:64:v8A">
<description>Generic ARM64 v8.5-A LE instructions, BE data, missing some 8.5 vector</description>
<compiler name="default" spec="AARCH64.cspec" id="default"/>
<external_name tool="gnu" name="aarch64"/>
<external_name tool="DWARF.register.mapping.file" name="AARCH64.dwarf"/>
</language>
<language processor="AARCH64"
endian="little"
size="32"
variant="ilp32"
version="1.5"
slafile="AARCH64.sla"
processorspec="AARCH64.pspec"
manualindexfile="../manuals/AARCH64.idx"
id="AARCH64:LE:32:ilp32">
<description>Generic ARM64 v8.5-A LE instructions, LE data, ilp32</description>
<truncate_space space="ram" size="4"/>
<compiler name="default" spec="AARCH64_ilp32.cspec" id="default"/>
<external_name tool="gnu" name="aarch64:ilp32"/>
<external_name tool="DWARF.register.mapping.file" name="AARCH64.dwarf"/>
</language>
<language processor="AARCH64"
endian="big"
instructionEndian="little"
size="32"
variant="ilp32"
version="1.5"
slafile="AARCH64BE.sla"
processorspec="AARCH64.pspec"
manualindexfile="../manuals/AARCH64.idx"
id="AARCH64:BE:32:ilp32">
<description>Generic ARM64 v8.5-A LE instructions, BE data, ilp32</description>
<truncate_space space="ram" size="4"/>
<compiler name="default" spec="AARCH64_ilp32.cspec" id="default"/>
<external_name tool="gnu" name="aarch64:ilp32"/>
<external_name tool="DWARF.register.mapping.file" name="AARCH64.dwarf"/>
</language>
</language_definitions>
@@ -0,0 +1,17 @@
<opinions>
<constraint loader="Executable and Linking Format (ELF)" compilerSpecID="default">
<constraint primary="183" processor="AARCH64" size="64" variant="v8A" />
</constraint>
<constraint loader="Executable and Linking Format (ELF)" compilerSpecID="default">
<constraint primary="183" processor="AARCH64" size="32" variant="ilp32" />
</constraint>
<constraint loader="Mac OS X Mach-O" compilerSpecID="default">
<constraint primary="16777228" processor="AARCH64" endian="little" size="64" variant="AppleSilicon" />
</constraint>
<constraint loader="DYLD Cache" compilerSpecID="default">
<constraint primary="AARCH64" processor="AARCH64" endian="little" size="64" variant="AppleSilicon" />
</constraint>
<constraint loader="Portable Executable (PE)" compilerSpecID="windows">
<constraint primary="43620" processor="AARCH64" endian="little" size="64" variant="v8A" />
</constraint>
</opinions>
@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<processor_spec>
<properties>
<property key="addressesDoNotAppearDirectlyInCode" value="true"/>
<property key="allowOffcutReferencesToFunctionStarts" value="false"/>
<property key="useNewFunctionStackAnalysis" value="true"/>
<property key="emulateInstructionStateModifierClass"
value="ghidra.program.emulation.AARCH64EmulateInstructionStateModifier"/>
<property key="assemblyRating:AARCH64:BE:64:v8A" value="PLATINUM"/>
<property key="assemblyRating:AARCH64:LE:64:v8A" value="PLATINUM"/>
</properties>
<programcounter register="pc"/>
<!-- The context_data's context_set initializes the given registers to the given values. -->
<context_data>
<context_set space="ram">
<!-- These context registers are only modified by the user, e.g. with the "Set Registers..." command. -->
<set name="ShowPAC" val="0" description="1 to show PAC operations in decompiler"/>
<set name="PAC_clobber" val="0" description="1 to let PAC operations overwrite their operands in decompiler"/>
<set name="ShowBTI" val="0" description="1 to show BTI effects in decompiler"/>
<set name="ShowMemTag" val="0" description="1 to show memory tag checks in decompiler"/>
</context_set>
</context_data>
<default_symbols>
<symbol name="Reset" address="ram:0x0" entry="true"/>
</default_symbols>
<volatile outputop="cWrite" inputop="cRead">
<range space="register" first="0x1000" last="0x3fff"/>
</volatile>
<register_data>
<register name="z0" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z1" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z2" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z3" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z4" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z5" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z6" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z7" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z8" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z9" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z10" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z11" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z12" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z13" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z14" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z15" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z16" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z17" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z18" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z19" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z20" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z21" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z22" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z23" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z24" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z25" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z26" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z27" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z28" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z29" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z30" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="z31" group="SVE" vector_lane_sizes="1,2,4,8"/>
<register name="q0" vector_lane_sizes="1,2,4,8"/>
<register name="q1" vector_lane_sizes="1,2,4,8"/>
<register name="q2" vector_lane_sizes="1,2,4,8"/>
<register name="q3" vector_lane_sizes="1,2,4,8"/>
<register name="q4" vector_lane_sizes="1,2,4,8"/>
<register name="q5" vector_lane_sizes="1,2,4,8"/>
<register name="q6" vector_lane_sizes="1,2,4,8"/>
<register name="q7" vector_lane_sizes="1,2,4,8"/>
<register name="q8" vector_lane_sizes="1,2,4,8"/>
<register name="q9" vector_lane_sizes="1,2,4,8"/>
<register name="q10" vector_lane_sizes="1,2,4,8"/>
<register name="q11" vector_lane_sizes="1,2,4,8"/>
<register name="q12" vector_lane_sizes="1,2,4,8"/>
<register name="q13" vector_lane_sizes="1,2,4,8"/>
<register name="q14" vector_lane_sizes="1,2,4,8"/>
<register name="q15" vector_lane_sizes="1,2,4,8"/>
<register name="q16" vector_lane_sizes="1,2,4,8"/>
<register name="q17" vector_lane_sizes="1,2,4,8"/>
<register name="q18" vector_lane_sizes="1,2,4,8"/>
<register name="q19" vector_lane_sizes="1,2,4,8"/>
<register name="q20" vector_lane_sizes="1,2,4,8"/>
<register name="q21" vector_lane_sizes="1,2,4,8"/>
<register name="q22" vector_lane_sizes="1,2,4,8"/>
<register name="q23" vector_lane_sizes="1,2,4,8"/>
<register name="q24" vector_lane_sizes="1,2,4,8"/>
<register name="q25" vector_lane_sizes="1,2,4,8"/>
<register name="q26" vector_lane_sizes="1,2,4,8"/>
<register name="q27" vector_lane_sizes="1,2,4,8"/>
<register name="q28" vector_lane_sizes="1,2,4,8"/>
<register name="q29" vector_lane_sizes="1,2,4,8"/>
<register name="q30" vector_lane_sizes="1,2,4,8"/>
<register name="q31" vector_lane_sizes="1,2,4,8"/>
</register_data>
</processor_spec>
@@ -0,0 +1,5 @@
@define DATA_ENDIAN "little"
@include "AARCH64instructions.sinc"
@@ -0,0 +1,5 @@
@define DATA_ENDIAN "big"
@include "AARCH64instructions.sinc"
@@ -0,0 +1,171 @@
#
# Apple AARCH64 extended matrix instructions
# Contents based on evolving information published on Web
#
#
define pcodeop __amx_ldx;
define pcodeop __amx_ldy;
define pcodeop __amx_stx;
define pcodeop __amx_sty;
define pcodeop __amx_ldz;
define pcodeop __amx_stz;
define pcodeop __amx_ldzi;
define pcodeop __amx_stzi;
define pcodeop __amx_extrx;
define pcodeop __amx_extry;
define pcodeop __amx_fma64;
define pcodeop __amx_fms64;
define pcodeop __amx_fma32;
define pcodeop __amx_fms32;
define pcodeop __amx_mac16;
define pcodeop __amx_fma16;
define pcodeop __amx_fms16;
define pcodeop __amx_enable;
define pcodeop __amx_disable;
define pcodeop __amx_vecint;
define pcodeop __amx_vecfp;
define pcodeop __amx_matint;
define pcodeop __amx_matfp;
define pcodeop __amx_genlut;
with : ImmS_ImmR_TestSet=1 {
AMXAddr: is Rd_GPR64 {
addr:8 = Rd_GPR64 & 0x00FFFFFFFFFFFFFF;
export addr;
}
AMXRegOff: is Rd_GPR64 {
registerOff:8 = (Rd_GPR64 >> 56) & 0x1F;
export registerOff;
}
AMXSize: is Rd_GPR64 {
local size = ((Rd_GPR64 >> 62) & 1);
size = zext(size == 0) * 0x40 | zext(size ==1 ) * 0x80;
export size;
}
:__amx_ldx Rd_GPR64 is b_2431=0x00 & b_1623=0x20 & b_1215=1 & b_1011=0 & b_0509=0 & AMXAddr & AMXRegOff & AMXSize & Rd_GPR64
{
__amx_ldx(Rd_GPR64);
}
:__amx_ldy Rd_GPR64 is b_2431=0x00 & b_1623=0x20 & b_1215=1 & b_1011=0 & b_0509=1 & AMXAddr & AMXRegOff & AMXSize & Rd_GPR64
{
__amx_ldy(Rd_GPR64);
}
:__amx_stx Rd_GPR64 is b_2431=0x00 & b_1623=0x20 & b_1215=1 & b_1011=0 & b_0509=2 & AMXAddr & AMXRegOff & AMXSize & Rd_GPR64
{
__amx_stx(Rd_GPR64);
}
:__amx_sty Rd_GPR64 is b_2431=0x00 & b_1623=0x20 & b_1215=1 & b_1011=0 & b_0509=3 & AMXAddr & AMXRegOff & AMXSize & Rd_GPR64
{
__amx_sty(Rd_GPR64);
}
:__amx_ldz Rd_GPR64 is b_2431=0x00 & b_1623=0x20 & b_1215=1 & b_1011=0 & b_0509=4 & AMXAddr & AMXRegOff & AMXSize & Rd_GPR64
{
__amx_ldz(Rd_GPR64);
}
:__amx_stz Rd_GPR64 is b_2431=0x00 & b_1623=0x20 & b_1215=1 & b_1011=0 & b_0509=5 & AMXAddr & AMXRegOff & AMXSize & Rd_GPR64
{
__amx_stz(Rd_GPR64);
}
:__amx_ldzi Rd_GPR64 is b_2431=0x00 & b_1623=0x20 & b_1215=1 & b_1011=0 & b_0509=6 & AMXAddr & AMXRegOff & AMXSize & Rd_GPR64
{
__amx_ldzi(Rd_GPR64);
}
:__amx_stzi Rd_GPR64 is b_2431=0x00 & b_1623=0x20 & b_1215=1 & b_1011=0 & b_0509=7 & AMXAddr & AMXRegOff & AMXSize & Rd_GPR64
{
__amx_stzi(Rd_GPR64);
}
:__amx_extrx Rd_GPR64 is b_2431=0x00 & b_1623=0x20 & b_1215=1 & b_1011=0 & b_0509=8 & Rd_GPR64
{
__amx_extrx(Rd_GPR64);
}
:__amx_extry Rd_GPR64 is b_2431=0x00 & b_1623=0x20 & b_1215=1 & b_1011=0 & b_0509=9 & Rd_GPR64
{
__amx_extry(Rd_GPR64);
}
:__amx_fma64 Rd_GPR64 is b_2431=0x00 & b_1623=0x20 & b_1215=1 & b_1011=0 & b_0509=10 & Rd_GPR64
{
__amx_fma64(Rd_GPR64);
}
:__amx_fms64 Rd_GPR64 is b_2431=0x00 & b_1623=0x20 & b_1215=1 & b_1011=0 & b_0509=11 & Rd_GPR64
{
__amx_fms64(Rd_GPR64);
}
:__amx_fma32 Rd_GPR64 is b_2431=0x00 & b_1623=0x20 & b_1215=1 & b_1011=0 & b_0509=12 & Rd_GPR64
{
__amx_fma32(Rd_GPR64);
}
:__amx_fms32 Rd_GPR64 is b_2431=0x00 & b_1623=0x20 & b_1215=1 & b_1011=0 & b_0509=13 & Rd_GPR64
{
__amx_fms32(Rd_GPR64);
}
:__amx_mac16 Rd_GPR64 is b_2431=0x00 & b_1623=0x20 & b_1215=1 & b_1011=0 & b_0509=14 & Rd_GPR64
{
__amx_mac16(Rd_GPR64);
}
:__amx_fma16 Rd_GPR64 is b_2431=0x00 & b_1623=0x20 & b_1215=1 & b_1011=0 & b_0509=15 & Rd_GPR64
{
__amx_fma16(Rd_GPR64);
}
:__amx_fms16 Rd_GPR64 is b_2431=0x00 & b_1623=0x20 & b_1215=1 & b_1011=0 & b_0509=16 & Rd_GPR64
{
__amx_fms16(Rd_GPR64);
}
:__amxdisable is b_2431=0x00 & b_1623=0x20 & b_1215=1 & b_1011=0 & b_0509=17 & b_0004=1
{
__amx_disable();
}
:__amxenable is b_2431=0x00 & b_1623=0x20 & b_1215=1 & b_1011=0 & b_0509=17 & b_0004=0
{
__amx_enable();
}
:__amx_vecint Rd_GPR64 is b_2431=0x00 & b_1623=0x20 & b_1215=1 & b_1011=0 & b_0509=18 & Rd_GPR64
{
__amx_vecint(Rd_GPR64);
}
:__amx_vecfp Rd_GPR64 is b_2431=0x00 & b_1623=0x20 & b_1215=1 & b_1011=0 & b_0509=19 & Rd_GPR64
{
__amx_vecfp(Rd_GPR64);
}
:__amx_matint Rd_GPR64 is b_2431=0x00 & b_1623=0x20 & b_1215=1 & b_1011=0 & b_0509=20 & Rd_GPR64
{
__amx_matint(Rd_GPR64);
}
:__amx_matfp Rd_GPR64 is b_2431=0x00 & b_1623=0x20 & b_1215=1 & b_1011=0 & b_0509=21 & Rd_GPR64
{
__amx_matfp(Rd_GPR64);
}
:__amx_genlut Rd_GPR64 is b_2431=0x00 & b_1623=0x20 & b_1215=1 & b_1011=0 & b_0509=22 & Rd_GPR64
{
__amx_genlut(Rd_GPR64);
}
}
@@ -0,0 +1,6 @@
@define DATA_ENDIAN "little"
@include "AARCH64instructions.sinc"
@include "AARCH64_AMXext.sinc"
@@ -0,0 +1,164 @@
autda__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 & Rn_GPR64xsp & Rd_GPR64 { Rd_GPR64 = AuthDA(Rd_GPR64, Rn_GPR64xsp); }
autda__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 & Rn_GPR64xsp & Rd_GPR64 { AuthDA(Rd_GPR64, Rn_GPR64xsp); }
autda__PACpart: "hide" is ShowPAC=0 { }
autdza__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 & Rd_GPR64 { Rd_GPR64 = AuthDA(Rd_GPR64, xzr); }
autdza__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 & Rd_GPR64 { AuthDA(Rd_GPR64, xzr); }
autdza__PACpart: "hide" is ShowPAC=0 { }
autdb__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 & Rn_GPR64xsp & Rd_GPR64 { Rd_GPR64 = AuthDB(Rd_GPR64, Rn_GPR64xsp); }
autdb__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 & Rn_GPR64xsp & Rd_GPR64 { AuthDB(Rd_GPR64, Rn_GPR64xsp); }
autdb__PACpart: "hide" is ShowPAC=0 { }
autdzb__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 & Rd_GPR64 { Rd_GPR64 = AuthDB(Rd_GPR64, xzr); }
autdzb__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 & Rd_GPR64 { AuthDB(Rd_GPR64, xzr); }
autdzb__PACpart: "hide" is ShowPAC=0 { }
autia__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 & Rn_GPR64xsp & Rd_GPR64 { Rd_GPR64 = AuthIA(Rd_GPR64, Rn_GPR64xsp); }
autia__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 & Rn_GPR64xsp & Rd_GPR64 { AuthIA(Rd_GPR64, Rn_GPR64xsp); }
autia__PACpart: "hide" is ShowPAC=0 { }
autiza__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 & Rd_GPR64 { Rd_GPR64 = AuthIA(Rd_GPR64, xzr); }
autiza__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 & Rd_GPR64 { AuthIA(Rd_GPR64, xzr); }
autiza__PACpart: "hide" is ShowPAC=0 { }
autia1716__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 { x17 = AuthIA(x17, x16); }
autia1716__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 { AuthIA(x17, x16); }
autia1716__PACpart: "hide" is ShowPAC=0 { }
autiasp__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 { x30 = AuthIA(x30, sp); }
autiasp__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 { AuthIA(x30, sp); }
autiasp__PACpart: "hide" is ShowPAC=0 { }
autiaz__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 { x30 = AuthIA(x30, xzr); }
autiaz__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 { AuthIA(x30, xzr); }
autiaz__PACpart: "hide" is ShowPAC=0 { }
autib__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 & Rn_GPR64xsp & Rd_GPR64 { Rd_GPR64 = AuthIB(Rd_GPR64, Rn_GPR64xsp); }
autib__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 & Rn_GPR64xsp & Rd_GPR64 { AuthIB(Rd_GPR64, Rn_GPR64xsp); }
autib__PACpart: "hide" is ShowPAC=0 { }
autizb__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 & Rd_GPR64 { Rd_GPR64 = AuthIB(Rd_GPR64, xzr); }
autizb__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 & Rd_GPR64 { AuthIB(Rd_GPR64, xzr); }
autizb__PACpart: "hide" is ShowPAC=0 { }
autib1716__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 { x17 = AuthIB(x17, x16); }
autib1716__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 { AuthIB(x17, x16); }
autib1716__PACpart: "hide" is ShowPAC=0 { }
autibsp__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 { x30 = AuthIB(x30, sp); }
autibsp__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 { AuthIB(x30, sp); }
autibsp__PACpart: "hide" is ShowPAC=0 { }
autibz__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 { x30 = AuthIB(x30, xzr); }
autibz__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 { AuthIB(x30, xzr); }
autibz__PACpart: "hide" is ShowPAC=0 { }
b_blinkop__raaz___PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 & Rn_GPR64 { AuthIA(Rn_GPR64, xzr); }
b_blinkop__raaz___PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 & Rn_GPR64 { AuthIA(Rn_GPR64, xzr); }
b_blinkop__raaz___PACpart: "hide" is ShowPAC=0 { }
b_blinkop__raa___PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 & Rd_GPR64xsp & Rn_GPR64 { AuthIA(Rn_GPR64, Rd_GPR64xsp); }
b_blinkop__raa___PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 & Rd_GPR64xsp & Rn_GPR64 { AuthIA(Rn_GPR64, Rd_GPR64xsp); }
b_blinkop__raa___PACpart: "hide" is ShowPAC=0 { }
b_blinkop__rabz___PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 & Rn_GPR64 { AuthIB(Rn_GPR64, xzr); }
b_blinkop__rabz___PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 & Rn_GPR64 { AuthIB(Rn_GPR64, xzr); }
b_blinkop__rabz___PACpart: "hide" is ShowPAC=0 { }
b_blinkop__rab___PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 & Rd_GPR64xsp & Rn_GPR64 { AuthIB(Rn_GPR64, Rd_GPR64xsp); }
b_blinkop__rab___PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 & Rd_GPR64xsp & Rn_GPR64 { AuthIB(Rn_GPR64, Rd_GPR64xsp); }
b_blinkop__rab___PACpart: "hide" is ShowPAC=0 { }
eretaa__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 { AuthIA(pc, sp); }
eretaa__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 { AuthIA(pc, sp); }
eretaa__PACpart: "hide" is ShowPAC=0 { }
eretab__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 { AuthIB(pc, sp); }
eretab__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 { AuthIB(pc, sp); }
eretab__PACpart: "hide" is ShowPAC=0 { }
ldraa__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 & Rn_GPR64xsp { AuthDA(Rn_GPR64xsp, xzr); }
ldraa__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 & Rn_GPR64xsp { AuthDA(Rn_GPR64xsp, xzr); }
ldraa__PACpart: "hide" is ShowPAC=0 { }
ldrab__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 & Rn_GPR64xsp { AuthDB(Rn_GPR64xsp, xzr); }
ldrab__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 & Rn_GPR64xsp { AuthDB(Rn_GPR64xsp, xzr); }
ldrab__PACpart: "hide" is ShowPAC=0 { }
pacda__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 & Rn_GPR64xsp & Rd_GPR64 { Rd_GPR64 = pacda(Rd_GPR64, Rn_GPR64xsp); }
pacda__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 & Rn_GPR64xsp & Rd_GPR64 { pacda(Rd_GPR64, Rn_GPR64xsp); }
pacda__PACpart: "hide" is ShowPAC=0 { }
pacdza__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 & Rd_GPR64 { Rd_GPR64 = pacdza(Rd_GPR64); }
pacdza__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 & Rd_GPR64 { pacdza(Rd_GPR64); }
pacdza__PACpart: "hide" is ShowPAC=0 { }
pacdb__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 & Rn_GPR64xsp & Rd_GPR64 { Rd_GPR64 = pacdb(Rd_GPR64, Rn_GPR64xsp); }
pacdb__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 & Rn_GPR64xsp & Rd_GPR64 { pacdb(Rd_GPR64, Rn_GPR64xsp); }
pacdb__PACpart: "hide" is ShowPAC=0 { }
pacdzb__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 & Rd_GPR64 { Rd_GPR64 = pacdzb(Rd_GPR64); }
pacdzb__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 & Rd_GPR64 { pacdzb(Rd_GPR64); }
pacdzb__PACpart: "hide" is ShowPAC=0 { }
pacia__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 & Rn_GPR64xsp & Rd_GPR64 { Rd_GPR64 = pacia(Rd_GPR64, Rn_GPR64xsp); }
pacia__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 & Rn_GPR64xsp & Rd_GPR64 { pacia(Rd_GPR64, Rn_GPR64xsp); }
pacia__PACpart: "hide" is ShowPAC=0 { }
paciza__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 & Rd_GPR64 { Rd_GPR64 = paciza(Rd_GPR64); }
paciza__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 & Rd_GPR64 { paciza(Rd_GPR64); }
paciza__PACpart: "hide" is ShowPAC=0 { }
pacia1716__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 { x17 = pacia(x17, x16); }
pacia1716__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 { pacia(x17, x16); }
pacia1716__PACpart: "hide" is ShowPAC=0 { }
paciasp__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 { x30 = pacia(x30, sp); }
paciasp__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 { pacia(x30, sp); }
paciasp__PACpart: "hide" is ShowPAC=0 { }
paciaz__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 { x30 = paciza(x30); }
paciaz__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 { paciza(x30); }
paciaz__PACpart: "hide" is ShowPAC=0 { }
pacib__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 & Rn_GPR64xsp & Rd_GPR64 { Rd_GPR64 = pacib(Rd_GPR64, Rn_GPR64xsp); }
pacib__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 & Rn_GPR64xsp & Rd_GPR64 { pacib(Rd_GPR64, Rn_GPR64xsp); }
pacib__PACpart: "hide" is ShowPAC=0 { }
pacizb__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 & Rd_GPR64 { Rd_GPR64 = pacizb(Rd_GPR64); }
pacizb__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 & Rd_GPR64 { pacizb(Rd_GPR64); }
pacizb__PACpart: "hide" is ShowPAC=0 { }
pacib1716__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 { x17 = pacib(x17, x16); }
pacib1716__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 { pacib(x17, x16); }
pacib1716__PACpart: "hide" is ShowPAC=0 { }
pacibsp__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 { x30 = pacib(x30, sp); }
pacibsp__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 { pacib(x30, sp); }
pacibsp__PACpart: "hide" is ShowPAC=0 { }
pacibz__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 { x30 = pacizb(x30); }
pacibz__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 { pacizb(x30); }
pacibz__PACpart: "hide" is ShowPAC=0 { }
retaa__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 { AuthIA(x30, sp); }
retaa__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 { AuthIA(x30, sp); }
retaa__PACpart: "hide" is ShowPAC=0 { }
retab__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 { AuthIB(x30, sp); }
retab__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 { AuthIB(x30, sp); }
retab__PACpart: "hide" is ShowPAC=0 { }
xpacd__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 & Rd_GPR64 { Rd_GPR64 = xpac(Rd_GPR64, 1:1); }
xpacd__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 & Rd_GPR64 { xpac(Rd_GPR64, 1:1); }
xpacd__PACpart: "hide" is ShowPAC=0 { }
xpaci__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 & Rd_GPR64 { Rd_GPR64 = xpac(Rd_GPR64, 0:1); }
xpaci__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 & Rd_GPR64 { xpac(Rd_GPR64, 0:1); }
xpaci__PACpart: "hide" is ShowPAC=0 { }
xpaclri__PACpart: "show_and_clobber" is ShowPAC=1 & PAC_clobber=1 { x30 = xpac(x30, 0:1); }
xpaclri__PACpart: "show_noclobber" is ShowPAC=1 & PAC_clobber=0 { xpac(x30, 0:1); }
xpaclri__PACpart: "hide" is ShowPAC=0 { }
@@ -0,0 +1,207 @@
<?xml version="1.0" encoding="UTF-8"?>
<compiler_spec>
<data_organization>
<absolute_max_alignment value="0" />
<machine_alignment value="4" />
<default_alignment value="1" />
<default_pointer_alignment value="8" />
<pointer_size value="4" />
<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"/>
<!-- The decompiler will treat registers in this range as global variables.
ie: tmp_ldWn, tmp_ldXn, tmp_stWn, tmp_stXn -->
<range space="register" first="0x3000" last="0x3fff"/>
</global>
<aggressivetrim signext="true"/> <!-- Aggressively try to eliminate sign extensions -->
<stackpointer register="sp" space="ram"/>
<funcptr align="4"/> <!-- Function pointers are word aligned and leastsig bit may encode otherstuff -->
<prefersplit style="inhalf">
<register name="q0"/>
<register name="q1"/>
<register name="q2"/>
<register name="q3"/>
<register name="q4"/>
<register name="q5"/>
<register name="q6"/>
<register name="q7"/>
<register name="q8"/>
<register name="q9"/>
<register name="q10"/>
<register name="q11"/>
<register name="q12"/>
<register name="q13"/>
<register name="q14"/>
<register name="q15"/>
<register name="q16"/>
<register name="q17"/>
<register name="q18"/>
<register name="q19"/>
<register name="q20"/>
<register name="q21"/>
<register name="q22"/>
<register name="q23"/>
<register name="q24"/>
<register name="q25"/>
<register name="q26"/>
<register name="q27"/>
<register name="q28"/>
<register name="q29"/>
<register name="q30"/>
</prefersplit>
<default_proto>
<prototype name="__cdecl" extrapop="0" stackshift="0">
<input>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d0"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d1"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d2"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d3"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d4"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d5"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d6"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d7"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x0"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x1"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x2"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x3"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x4"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x5"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x6"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x7"/>
</pentry>
<pentry minsize="1" maxsize="500" align="4">
<addr offset="0" space="stack"/>
</pentry>
</input>
<output>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d0"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x0"/>
</pentry>
<pentry minsize="9" maxsize="16" extension="zero">
<addr space="join" piece1="x1" piece2="x0"/>
</pentry>
</output>
<unaffected>
<register name="x19"/>
<register name="x20"/>
<register name="x21"/>
<register name="x22"/>
<register name="x23"/>
<register name="x24"/>
<register name="x25"/>
<register name="x26"/>
<register name="x27"/>
<register name="x28"/>
<register name="x29"/>
<register name="x30"/>
<register name="sp"/>
<!-- vectors -->
<register name="d8"/>
<register name="d9"/>
<register name="d10"/>
<register name="d11"/>
<register name="d12"/>
<register name="d13"/>
<register name="d14"/>
<register name="d15"/>
</unaffected>
<killedbycall>
<!-- x8: indirect result location register, which is not
reflected in the pentry list -->
<register name="x8"/>
<register name="x9"/>
<register name="x10"/>
<register name="x11"/>
<register name="x12"/>
<register name="x13"/>
<register name="x14"/>
<register name="x15"/>
<register name="x16"/>
<register name="x17"/>
<register name="x18"/>
<!-- vectors -->
<register name="d16"/>
<register name="d17"/>
<register name="d18"/>
<register name="d19"/>
<register name="d20"/>
<register name="d21"/>
<register name="d22"/>
<register name="d23"/>
<register name="d24"/>
<register name="d25"/>
<register name="d26"/>
<register name="d27"/>
<register name="d28"/>
<register name="d29"/>
<register name="d30"/>
<register name="d31"/>
</killedbycall>
</prototype>
</default_proto>
<callfixup name="PlaceHolderCallFixup"> <!-- This is here just to force call fixup and NoReturn fixup. Will be fixed in Ghidra V6.0 -->
<target name="___NotARealFunctionName___"/>
<pcode>
<body><![CDATA[
tmpptr:4 = 0;
]]></body>
</pcode>
</callfixup>
</compiler_spec>
@@ -0,0 +1,214 @@
<?xml version="1.0" encoding="UTF-8"?>
<compiler_spec>
<!-- Copied from AARCH.cspec and modified...
See: https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions?view=vs-2019
The AARCH64 ABI refers to Windows ABI as LLP64 data model -->
<data_organization>
<absolute_max_alignment value="0" />
<machine_alignment value="4" />
<default_alignment value="1" />
<default_pointer_alignment value="8" />
<pointer_size value="8" />
<wchar_size value="2" />
<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="16" />
<size_alignment_map>
<entry size="1" alignment="1" />
<entry size="2" alignment="2" />
<entry size="4" alignment="4" />
<entry size="8" alignment="8" />
<entry size="16" alignment="16" />
</size_alignment_map>
<bitfield_packing>
<use_MS_convention value="true"/>
</bitfield_packing>
</data_organization>
<global>
<range space="ram"/>
</global>
<stackpointer register="sp" space="ram"/>
<funcptr align="4"/> <!-- Function pointers are word aligned and leastsig bit may encode otherstuff -->
<prefersplit style="inhalf">
<register name="q0"/>
<register name="q1"/>
<register name="q2"/>
<register name="q3"/>
<register name="q4"/>
<register name="q5"/>
<register name="q6"/>
<register name="q7"/>
<register name="q8"/>
<register name="q9"/>
<register name="q10"/>
<register name="q11"/>
<register name="q12"/>
<register name="q13"/>
<register name="q14"/>
<register name="q15"/>
<register name="q16"/>
<register name="q17"/>
<register name="q18"/>
<register name="q19"/>
<register name="q20"/>
<register name="q21"/>
<register name="q22"/>
<register name="q23"/>
<register name="q24"/>
<register name="q25"/>
<register name="q26"/>
<register name="q27"/>
<register name="q28"/>
<register name="q29"/>
<register name="q30"/>
</prefersplit>
<default_proto>
<prototype name="__cdecl" extrapop="0" stackshift="0">
<input>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d0"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d1"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d2"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d3"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d4"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d5"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d6"/>
</pentry>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d7"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x0"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x1"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x2"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x3"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x4"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x5"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x6"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x7"/>
</pentry>
<pentry minsize="1" maxsize="500" align="4">
<addr offset="0" space="stack"/>
</pentry>
</input>
<output>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d0"/>
</pentry>
<pentry minsize="1" maxsize="8" extension="zero">
<register name="x0"/>
</pentry>
</output>
<unaffected>
<register name="x19"/>
<register name="x20"/>
<register name="x21"/>
<register name="x22"/>
<register name="x23"/>
<register name="x24"/>
<register name="x25"/>
<register name="x26"/>
<register name="x27"/>
<register name="x28"/>
<register name="x29"/>
<register name="x30"/>
<register name="sp"/>
<!-- vectors -->
<register name="d8"/>
<register name="d9"/>
<register name="d10"/>
<register name="d11"/>
<register name="d12"/>
<register name="d13"/>
<register name="d14"/>
<register name="d15"/>
</unaffected>
<killedbycall>
<!-- x8: indirect result location register, which is not
reflected in the pentry list -->
<register name="x8"/>
<register name="x9"/>
<register name="x10"/>
<register name="x11"/>
<register name="x12"/>
<register name="x13"/>
<register name="x14"/>
<register name="x15"/>
<register name="x16"/>
<register name="x17"/>
<register name="x18"/>
<!-- vectors -->
<register name="d16"/>
<register name="d17"/>
<register name="d18"/>
<register name="d19"/>
<register name="d20"/>
<register name="d21"/>
<register name="d22"/>
<register name="d23"/>
<register name="d24"/>
<register name="d25"/>
<register name="d26"/>
<register name="d27"/>
<register name="d28"/>
<register name="d29"/>
<register name="d30"/>
<register name="d31"/>
</killedbycall>
</prototype>
</default_proto>
<callfixup name="security_push_cookie">
<target name="__security_push_cookie"/>
<pcode>
<body><![CDATA[
sp = sp - 16;
]]></body>
</pcode>
</callfixup>
<callfixup name="security_pop_cookie">
<target name="__security_pop_cookie"/>
<pcode>
<body><![CDATA[
sp = sp + 16;
]]></body>
</pcode>
</callfixup>
</compiler_spec>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,18 @@
<?xml version="1.1" encoding="UTF-8"?>
<language_definitions>
<language processor="AARCH64"
endian="little"
size="64"
variant="AppleSilicon"
version="1.5"
slafile="AARCH64_AppleSilicon.sla"
processorspec="AARCH64.pspec"
manualindexfile="../manuals/AARCH64.idx"
id="AARCH64:LE:64:AppleSilicon">
<description>AppleSilicon ARM v8.5-A LE instructions, LE data, AMX extensions</description>
<compiler name="default" spec="AARCH64.cspec" id="default"/>
<external_name tool="gnu" name="aarch64"/>
<external_name tool="gnu" name="aarch64:ilp32"/>
<external_name tool="DWARF.register.mapping.file" name="AARCH64.dwarf"/>
</language>
</language_definitions>
@@ -0,0 +1,266 @@
<?xml version="1.0" encoding="UTF-8"?>
<compiler_spec>
<!--
Assumes Procedure Call Standard for the ARM Architecture (AAPCS) Applies.
-->
<data_organization> <!-- These tags were generated with gcc 4.2.4 -->
<absolute_max_alignment value="0" />
<machine_alignment value="2" />
<default_alignment value="1" />
<default_pointer_alignment value="4" />
<pointer_size value="4" />
<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"/>
</global>
<stackpointer register="sp" space="ram"/>
<funcptr align="2"/> <!-- Function pointers are word aligned and leastsig bit may encode otherstuff -->
<default_proto>
<prototype name="__stdcall" extrapop="0" stackshift="0">
<input>
<pentry minsize="1" maxsize="4" metatype="float">
<register name="s0"/>
</pentry>
<pentry minsize="1" maxsize="4" metatype="float">
<register name="s1"/>
</pentry>
<pentry minsize="1" maxsize="4" metatype="float">
<register name="s2"/>
</pentry>
<pentry minsize="1" maxsize="4" metatype="float">
<register name="s3"/>
</pentry>
<pentry minsize="1" maxsize="4" metatype="float">
<register name="s4"/>
</pentry>
<pentry minsize="1" maxsize="4" metatype="float">
<register name="s5"/>
</pentry>
<pentry minsize="1" maxsize="4" metatype="float">
<register name="s6"/>
</pentry>
<pentry minsize="1" maxsize="4" metatype="float">
<register name="s7"/>
</pentry>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="r0"/>
</pentry>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="r1"/>
</pentry>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="r2"/>
</pentry>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="r3"/>
</pentry>
<pentry minsize="1" maxsize="500" align="4">
<addr offset="0" space="stack"/>
</pentry>
</input>
<output>
<pentry minsize="1" maxsize="8" metatype="float">
<register name="d0"/>
</pentry>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="r0"/>
</pentry>
<pentry minsize="5" maxsize="8">
<addr space="join" piece1="r1" piece2="r0"/>
</pentry>
</output>
<unaffected>
<register name="r4"/>
<register name="r5"/>
<register name="r6"/>
<register name="r7"/>
<register name="r8"/>
<register name="r9"/>
<register name="r10"/>
<register name="r11"/>
<register name="d8"/>
<register name="d9"/>
<register name="d10"/>
<register name="d11"/>
<register name="d12"/>
<register name="d13"/>
<register name="d14"/>
<register name="d15"/>
<register name="sp"/>
</unaffected>
<killedbycall>
<register name="r1"/>
<register name="d0"/>
<register name="d1"/>
<register name="d2"/>
<register name="d3"/>
<register name="d4"/>
<register name="d5"/>
<register name="d6"/>
<register name="d7"/>
</killedbycall>
</prototype>
</default_proto>
<prototype name="processEntry" extrapop="0" stackshift="0">
<input pointermax="4">
<pentry minsize="1" maxsize="4">
<register name="r0"/>
</pentry>
<pentry minsize="1" maxsize="500" align="4">
<addr offset="0" space="stack"/>
</pentry>
</input>
<output killedbycall="true">
<pentry minsize="1" maxsize="4">
<register name="r0"/>
</pentry>
</output>
<unaffected>
<register name="sp"/>
</unaffected>
</prototype>
<callfixup name="switch8_r3">
<target name="switch8_r3"/>
<target name="__ARM_common_switch8"/>
<pcode>
<body><![CDATA[
tmpptr = lr - 1;
tblsize = *:1 tmpptr;
r12 = zext(tblsize);
inbounds = r3 < r12;
if (!inbounds) goto <next1>;
offset = *:1 (lr + r3);
r3 = zext(offset);
<next1>
if (inbounds) goto <next2>;
offset = *:1 (lr + r12);
r3 = zext(offset);
<next2>
r3 = r3 * 2;
r12 = lr + r3;
ISAModeSwitch = (r12 & 1) != 1;
TB = ISAModeSwitch;
pc = r12 & 0xfffffffe;
goto [pc];
]]></body>
</pcode>
</callfixup>
<callfixup name="switch8_r0">
<target name="__gnu_thumb1_case_uqi"/>
<target name="switch8_r0"/>
<pcode>
<body><![CDATA[
tmpptr = lr & 0xfffffffe;
offset = *:1 (tmpptr + r0);
lr = lr + 2 * zext(offset);
ISAModeSwitch = (lr & 1) != 0;
TB = ISAModeSwitch;
pc = lr & 0xfffffffe;
goto [pc];
]]></body>
</pcode>
</callfixup>
<callfixup name="switchS8_r0">
<target name="__gnu_thumb1_case_sqi"/>
<target name="switchS8_r0"/>
<pcode>
<body><![CDATA[
tmpptr = lr & 0xfffffffe;
offset = *:1 (tmpptr + r0);
lr = lr + 2 * sext(offset);
ISAModeSwitch = (lr & 1) != 0;
TB = ISAModeSwitch;
pc = lr & 0xfffffffe;
goto [pc];
]]></body>
</pcode>
</callfixup>
<callfixup name="switch16_shi_r0">
<target name="__gnu_thumb1_case_shi"/>
<target name="switch16_shi_r0"/>
<pcode>
<body><![CDATA[
tmpptr = lr & 0xfffffffe;
index = r0 * 2;
offset = *:2 (tmpptr + index);
lr = lr + 2 * sext(offset);
ISAModeSwitch = (lr & 1) != 0;
TB = ISAModeSwitch;
pc = lr & 0xfffffffe;
goto [pc];
]]></body>
</pcode>
</callfixup>
<callfixup name="switch16_uhi_r0">
<target name="__gnu_thumb1_case_uhi"/>
<target name="switch16_shi_r0"/>
<pcode>
<body><![CDATA[
tmpptr = lr & 0xfffffffe;
index = r0 * 2;
offset = *:2 (tmpptr + index);
lr = lr + 2 * zext(offset);
ISAModeSwitch = (lr & 1) != 0;
TB = ISAModeSwitch;
pc = lr & 0xfffffffe;
goto [pc];
]]></body>
</pcode>
</callfixup>
<callfixup name="switch32_si_r0">
<target name="__gnu_thumb1_case_si"/>
<target name="switch32_si_r0"/>
<pcode>
<body><![CDATA[
tmpptr = (lr + 2) & 0xfffffffc;
index = r0 * 4;
offset = *:4 (tmpptr + index);
offset = offset * 4;
lr = lr + offset;
ISAModeSwitch = (lr & 1) != 0;
TB = ISAModeSwitch;
pc = lr & 0xfffffffe;
goto [pc];
]]></body>
</pcode>
</callfixup>
</compiler_spec>
@@ -0,0 +1,12 @@
<dwarf>
<register_mappings>
<register_mapping dwarf="0" ghidra="r0" auto_count="13"/> <!-- r0..r12 -->
<register_mapping dwarf="13" ghidra="sp" stackpointer="true"/>
<register_mapping dwarf="14" ghidra="lr"/>
<register_mapping dwarf="15" ghidra="pc"/>
<register_mapping dwarf="16" ghidra="fpsr"/>
<register_mapping dwarf="17" ghidra="cpsr"/>
</register_mappings>
<call_frame_cfa value="0"/>
<use_formal_parameter_storage/>
</dwarf>
@@ -0,0 +1,41 @@
<!--
This file determines the disassembler options sent to the GNU external disassembler.
You can see which options are available for all architectures in the objdump man page.
Given a version of objdump compiled for a specific architecture, you can see what options
are available with "objdump -i -m"
The options for ARM are:
"reg-names-std" (the default)
"reg-names-apcs"
"reg-names-raw"
"reg-names-apcs"
"reg-names-special-apcs"
"force-thumb" (force thumb disassembly)
"no-force-thumb" (force arm disassembly)
(see the objdump manpage for the precise details about the different register
naming options)
"optstring" is the string of options, and "display_prefix" is an optional prefix prepended to the
external disassembly field. In this file, "A: " is prepended to ARM disassembly, and
"T: " is prepended to Thumb disassembly.
To send multiple options, concatenate them into a CSV list. For example, "no-force-thumb,reg-names-raw"
is a valid optstring. You can also have a "global" element whose "optstring" attribute is
always sent to the GNU disassembler.
If there is not a context register defined, the global optstring is sent by itself (see x86-16.gdis for
an example). If there is a context register defined, the global optstring is prepended to the
optstring determined by a context register value.
This file must be listed in the .ldefs file for the processor, e.g.
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
-->
<gdis>
<context_register>TMode</context_register>
<options>
<option value="0x0" optstring="no-force-thumb" display_prefix = "A: "/>
<option value="0x1" optstring="force-thumb" display_prefix = "T: "/>
</options>
</gdis>
@@ -0,0 +1,377 @@
<?xml version="1.1" encoding="UTF-8"?>
<language_definitions>
<language processor="ARM"
endian="little"
size="32"
variant="v8"
version="1.107"
slafile="ARM8_le.sla"
processorspec="ARMt.pspec"
manualindexfile="../manuals/ARM.idx"
id="ARM:LE:32:v8">
<description>Generic ARM/Thumb v8 little endian</description>
<compiler name="default" spec="ARM.cspec" id="default"/>
<compiler name="Visual Studio" spec="ARM_win.cspec" id="windows"/>
<external_name tool="gnu" name="iwmmxt"/>
<external_name tool="gnu" name="armv8-a"/>
<external_name tool="gnu" name="armv8-r"/>
<external_name tool="gnu" name="armv8-m.base"/>
<external_name tool="gnu" name="armv8-m.main"/>
<external_name tool="gnu" name="armv8.1-m.main"/>
<external_name tool="gnu" name="arm_any"/>
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
<external_name tool="IDA-PRO" name="arm"/>
<external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/>
</language>
<language processor="ARM"
endian="little"
size="32"
variant="v8T"
version="1.107"
slafile="ARM8_le.sla"
processorspec="ARMtTHUMB.pspec"
manualindexfile="../manuals/ARM.idx"
id="ARM:LE:32:v8T">
<description>Generic ARM/Thumb v8 little endian (Thumb is default)</description>
<compiler name="default" spec="ARM.cspec" id="default"/>
<compiler name="Visual Studio" spec="ARM_win.cspec" id="windows"/>
<external_name tool="gnu" name="iwmmxt"/>
<external_name tool="gnu" name="arm_any"/>
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
<external_name tool="IDA-PRO" name="arm"/>
<external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/>
</language>
<language processor="ARM"
endian="big"
instructionEndian="little"
size="32"
variant="v8LEInstruction"
version="1.107"
slafile="ARM8_le.sla"
processorspec="ARMt.pspec"
manualindexfile="../manuals/ARM.idx"
id="ARM:LEBE:32:v8LEInstruction">
<description>Generic ARM/Thumb v8 little endian instructions and big endian data</description>
<compiler name="default" spec="ARM.cspec" id="default"/>
<compiler name="Visual Studio" spec="ARM.cspec" id="windows"/>
<external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/>
</language>
<language processor="ARM"
endian="big"
size="32"
variant="v8"
version="1.107"
slafile="ARM8_be.sla"
processorspec="ARMt.pspec"
manualindexfile="../manuals/ARM.idx"
id="ARM:BE:32:v8">
<description>Generic ARM/Thumb v8 big endian</description>
<compiler name="default" spec="ARM.cspec" id="default"/>
<external_name tool="gnu" name="iwmmxt"/>
<external_name tool="gnu" name="armv8-a"/>
<external_name tool="gnu" name="armv8-r"/>
<external_name tool="gnu" name="armv8-m.base"/>
<external_name tool="gnu" name="armv8-m.main"/>
<external_name tool="gnu" name="armv8.1-m.main"/>
<external_name tool="gnu" name="arm_any"/>
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
<external_name tool="IDA-PRO" name="armb"/>
<external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/>
</language>
<language processor="ARM"
endian="big"
size="32"
variant="v8T"
version="1.107"
slafile="ARM8_be.sla"
processorspec="ARMtTHUMB.pspec"
manualindexfile="../manuals/ARM.idx"
id="ARM:BE:32:v8T">
<description>Generic ARM/Thumb v8 big endian (Thumb is default)</description>
<compiler name="default" spec="ARM.cspec" id="default"/>
<external_name tool="gnu" name="iwmmxt"/>
<external_name tool="gnu" name="arm_any"/>
<external_name tool="IDA-PRO" name="armb"/>
<external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/>
</language>
<language processor="ARM"
endian="little"
size="32"
variant="v7"
version="1.107"
slafile="ARM7_le.sla"
processorspec="ARMt.pspec"
manualindexfile="../manuals/ARM.idx"
id="ARM:LE:32:v7">
<description>Generic ARM/Thumb v7 little endian</description>
<compiler name="default" spec="ARM.cspec" id="default"/>
<compiler name="Visual Studio" spec="ARM_win.cspec" id="windows"/>
<external_name tool="gnu" name="iwmmxt"/>
<external_name tool="gnu" name="armv7"/>
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
<external_name tool="IDA-PRO" name="arm"/>
<external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/>
</language>
<language processor="ARM"
endian="big"
instructionEndian="little"
size="32"
variant="v7LEInstruction"
version="1.107"
slafile="ARM7_le.sla"
processorspec="ARMt.pspec"
manualindexfile="../manuals/ARM.idx"
id="ARM:LEBE:32:v7LEInstruction">
<description>Generic ARM/Thumb v7 little endian instructions and big endian data</description>
<compiler name="default" spec="ARM.cspec" id="default"/>
<compiler name="Visual Studio" spec="ARM.cspec" id="windows"/>
<external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/>
</language>
<language processor="ARM"
endian="big"
size="32"
variant="v7"
version="1.107"
slafile="ARM7_be.sla"
processorspec="ARMt.pspec"
manualindexfile="../manuals/ARM.idx"
id="ARM:BE:32:v7">
<description>Generic ARM/Thumb v7 big endian</description>
<compiler name="default" spec="ARM.cspec" id="default"/>
<external_name tool="gnu" name="iwmmxt"/>
<external_name tool="gnu" name="armv7"/>
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
<external_name tool="IDA-PRO" name="armb"/>
<external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/>
</language>
<language processor="ARM"
endian="little"
size="32"
variant="Cortex"
version="1.107"
slafile="ARM7_le.sla"
processorspec="ARMCortex.pspec"
manualindexfile="../manuals/ARM.idx"
id="ARM:LE:32:Cortex">
<description>ARM Cortex / Thumb little endian</description>
<compiler name="default" spec="ARM.cspec" id="default"/>
<external_name tool="gnu" name="armv7e-m"/>
<external_name tool="gnu" name="armv6k"/>
<external_name tool="gnu" name="armv6kz"/>
<external_name tool="gnu" name="armv6-m"/>
<external_name tool="gnu" name="armv6s-m"/>
<external_name tool="IDA-PRO" name="arm"/>
<external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/>
</language>
<language processor="ARM"
endian="big"
size="32"
variant="Cortex"
version="1.107"
slafile="ARM7_be.sla"
processorspec="ARMCortex.pspec"
manualindexfile="../manuals/ARM.idx"
id="ARM:BE:32:Cortex">
<description>ARM Cortex / Thumb big endian</description>
<compiler name="default" spec="ARM.cspec" id="default"/>
<external_name tool="gnu" name="armv6k"/>
<external_name tool="gnu" name="armv6kz"/>
<external_name tool="gnu" name="armv6-m"/>
<external_name tool="gnu" name="armv6s-m"/>
<external_name tool="IDA-PRO" name="armb"/>
<external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/>
</language>
<language processor="ARM"
endian="little"
size="32"
variant="v6"
version="1.107"
slafile="ARM6_le.sla"
processorspec="ARMt_v6.pspec"
manualindexfile="../manuals/ARM.idx"
id="ARM:LE:32:v6">
<description>Generic ARM/Thumb v6 little endian</description>
<compiler name="default" spec="ARM_v45.cspec" id="default"/>
<external_name tool="gnu" name="xscale"/>
<external_name tool="gnu" name="armv6"/>
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
<external_name tool="IDA-PRO" name="arm"/>
<external_name tool="DWARF.register.mapping.file" name="ARM.dwarf"/>
<!-- change DWARF register mapping to ARMneon.dwarf if VFPv2 is enabled -->
<!-- <external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/> -->
</language>
<language processor="ARM"
endian="big"
size="32"
variant="v6"
version="1.107"
slafile="ARM6_be.sla"
processorspec="ARMt_v6.pspec"
manualindexfile="../manuals/ARM.idx"
id="ARM:BE:32:v6">
<description>Generic ARM/Thumb v6 big endian</description>
<compiler name="default" spec="ARM_v45.cspec" id="default"/>
<external_name tool="gnu" name="xscale"/>
<external_name tool="gnu" name="armv6"/>
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
<external_name tool="IDA-PRO" name="armb"/>
<external_name tool="DWARF.register.mapping.file" name="ARM.dwarf"/>
<!-- change DWARF register mapping to ARMneon.dwarf if VFPv2 is enabled -->
<!-- <external_name tool="DWARF.register.mapping.file" name="ARMneon.dwarf"/> -->
</language>
<language processor="ARM"
endian="little"
size="32"
variant="v5t"
version="1.107"
slafile="ARM5t_le.sla"
processorspec="ARMt_v45.pspec"
manualindexfile="../manuals/ARM.idx"
id="ARM:LE:32:v5t">
<description>Generic ARM/Thumb v5 little endian (T-variant)</description>
<compiler name="default" spec="ARM_v45.cspec" id="default"/>
<external_name tool="gnu" name="armv5t"/>
<external_name tool="gnu" name="armv5tej"/>
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
<external_name tool="IDA-PRO" name="arm"/>
<external_name tool="DWARF.register.mapping.file" name="ARM.dwarf"/>
</language>
<language processor="ARM"
endian="big"
size="32"
variant="v5t"
version="1.107"
slafile="ARM5t_be.sla"
processorspec="ARMt_v45.pspec"
manualindexfile="../manuals/ARM.idx"
id="ARM:BE:32:v5t">
<description>Generic ARM/Thumb v5 big endian (T-variant)</description>
<compiler name="default" spec="ARM_v45.cspec" id="default"/>
<external_name tool="gnu" name="armv5t"/>
<external_name tool="gnu" name="armv5tej"/>
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
<external_name tool="IDA-PRO" name="armb"/>
<external_name tool="DWARF.register.mapping.file" name="ARM.dwarf"/>
</language>
<language processor="ARM"
endian="little"
size="32"
variant="v5"
version="1.107"
slafile="ARM5_le.sla"
processorspec="ARM_v45.pspec"
manualindexfile="../manuals/ARM.idx"
id="ARM:LE:32:v5">
<description>Generic ARM v5 little endian</description>
<compiler name="default" spec="ARM_v45.cspec" id="default"/>
<external_name tool="gnu" name="armv5"/>
<external_name tool="IDA-PRO" name="arm"/>
<external_name tool="DWARF.register.mapping.file" name="ARM.dwarf"/>
</language>
<language processor="ARM"
endian="big"
size="32"
variant="v5"
version="1.101"
slafile="ARM5_be.sla"
processorspec="ARM_v45.pspec"
manualindexfile="../manuals/ARM.idx"
id="ARM:BE:32:v5">
<description>Generic ARM v5 big endian</description>
<compiler name="default" spec="ARM_v45.cspec" id="default"/>
<external_name tool="gnu" name="armv5"/>
<external_name tool="IDA-PRO" name="armb"/>
<external_name tool="DWARF.register.mapping.file" name="ARM.dwarf"/>
</language>
<language processor="ARM"
endian="little"
size="32"
variant="v4t"
version="1.107"
slafile="ARM4t_le.sla"
processorspec="ARMt_v45.pspec"
manualindexfile="../manuals/ARM.idx"
id="ARM:LE:32:v4t">
<description>Generic ARM/Thumb v4 little endian (T-variant)</description>
<compiler name="default" spec="ARM_v45.cspec" id="default"/>
<external_name tool="gnu" name="armv4t"/>
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
<external_name tool="IDA-PRO" name="arm"/>
<external_name tool="DWARF.register.mapping.file" name="ARM.dwarf"/>
</language>
<language processor="ARM"
endian="big"
size="32"
variant="v4t"
version="1.107"
slafile="ARM4t_be.sla"
processorspec="ARMt_v45.pspec"
manualindexfile="../manuals/ARM.idx"
id="ARM:BE:32:v4t">
<description>Generic ARM/Thumb v4 big endian (T-variant)</description>
<compiler name="default" spec="ARM_v45.cspec" id="default"/>
<external_name tool="gnu" name="armv4t"/>
<external_name tool="gdis.disassembler.options.file" name="ARM.gdis"/>
<external_name tool="IDA-PRO" name="armb"/>
<external_name tool="DWARF.register.mapping.file" name="ARM.dwarf"/>
</language>
<language processor="ARM"
endian="little"
size="32"
variant="v4"
version="1.107"
slafile="ARM4_le.sla"
processorspec="ARM_v45.pspec"
manualindexfile="../manuals/ARM.idx"
id="ARM:LE:32:v4">
<description>Generic ARM v4 little endian</description>
<compiler name="default" spec="ARM_v45.cspec" id="default"/>
<external_name tool="gnu" name="armv4"/>
<external_name tool="gnu" name="armv2"/>
<external_name tool="gnu" name="armv2a"/>
<external_name tool="gnu" name="armv3"/>
<external_name tool="gnu" name="armv3m"/>
<external_name tool="IDA-PRO" name="arm"/>
<external_name tool="DWARF.register.mapping.file" name="ARM.dwarf"/>
</language>
<language processor="ARM"
endian="big"
size="32"
variant="v4"
version="1.107"
slafile="ARM4_be.sla"
processorspec="ARM_v45.pspec"
manualindexfile="../manuals/ARM.idx"
id="ARM:BE:32:v4">
<description>Generic ARM v4 big endian</description>
<compiler name="default" spec="ARM_v45.cspec" id="default"/>
<external_name tool="gnu" name="armv4"/>
<external_name tool="gnu" name="armv2"/>
<external_name tool="gnu" name="armv2a"/>
<external_name tool="gnu" name="armv3"/>
<external_name tool="gnu" name="armv3m"/>
<external_name tool="IDA-PRO" name="armb"/>
<external_name tool="DWARF.register.mapping.file" name="ARM.dwarf"/>
</language>
</language_definitions>
@@ -0,0 +1,68 @@
<opinions>
<!--
NOTE: secondary key constraints can be matched at the bit level or as a hex value (if the
key is an integer value).
When matching at the bit level, prefix the secondary key constraint value with "0b", followed
by a sequence of 0's and 1's to specify the key value. Dots (".") can be used as a wild card
for individual bits. Space and underscores ("_") are ignored and can be used for formatting.
When matching a hex value, prefix the secondary key constraint value with "0x", followed
by the hex value. No wildcarding is supported.
-->
<constraint loader="Portable Executable (PE)">
<constraint compilerSpecID="windows">
<constraint primary="448" processor="ARM" endian="little" size="32" variant="v8" />
<constraint primary="450" processor="ARM" endian="little" size="32" variant="v8" /> <!-- ARM and Thumb, spec says only Thumb -->
<constraint primary="452" processor="ARM" endian="little" size="32" variant="v8" />
</constraint>
<constraint compilerSpecID="default">
<constraint primary="2560" processor="ARM" endian="big" size="32" variant="v8" />
</constraint>
</constraint>
<constraint loader="Debug Symbols (DBG)" compilerSpecID="windows">
<constraint primary="448" processor="ARM" endian="little" size="32" variant="v8" />
<constraint primary="450" processor="ARM" endian="little" size="32" variant="v8" /> <!-- ARM and Thumb, spec says only Thumb -->
<constraint primary="452" processor="ARM" endian="little" size="32" variant="v8" />
</constraint>
<constraint loader="Executable and Linking Format (ELF)" compilerSpecID="default">
<!--
Elf e_flags are used for the secondary attribute, the following are pulled from binutils include/elf/arm.h
/* Constants defined in AAELF. */
EF_ARM_BE8 0x00800000
EF_ARM_LE8 0x00400000
EF_ARM_EABIMASK 0xFF000000
EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK)
EF_ARM_EABI_UNKNOWN 0x00000000
EF_ARM_EABI_VER1 0x01000000
EF_ARM_EABI_VER2 0x02000000
EF_ARM_EABI_VER3 0x03000000
EF_ARM_EABI_VER4 0x04000000
EF_ARM_EABI_VER5 0x05000000
-->
<constraint primary="40" processor="ARM" size="32" variant="v8"
secondary= "0b .... .... 0... .... .... .... .... ...."/>
<constraint primary="40" processor="ARM" size="32" variant="v8LEInstruction"
secondary= "0b .... .... 1... .... .... .... .... ...."/> <!-- EF_ARM_BE8 -->
</constraint>
<constraint loader="Mac OS X Mach-O" compilerSpecID="default">
<constraint primary="12.0" processor="ARM" endian="little" size="32" variant="v8" /><!-- ARM all -->
<constraint primary="12.5" processor="ARM" endian="little" size="32" variant="v4t" /><!-- ARM v4T -->
<constraint primary="12.6" processor="ARM" endian="little" size="32" variant="v6" /><!-- ARM v6 -->
<constraint primary="12.9" processor="ARM" endian="little" size="32" variant="v8" /><!-- ARM v8 -->
<constraint primary="12.10" processor="ARM" endian="little" size="32" variant="v8" /><!-- ARM v8f -->
<constraint primary="12.11" processor="ARM" endian="little" size="32" variant="v8" /><!-- ARM v8s -->
<constraint primary="12.12" processor="ARM" endian="little" size="32" variant="v8" /><!-- ARM v8k -->
</constraint>
<constraint loader="DYLD Cache" compilerSpecID="default">
<constraint primary="armv6" processor="ARM" endian="little" size="32" variant="v6" />
<constraint primary="arm7" processor="ARM" endian="little" size="32" variant="v7" />
</constraint>
<constraint loader="MS Common Object File Format (COFF)" compilerSpecID="windows">
<constraint primary="448" processor="ARM" endian="little" size="32" variant="v8" />
<constraint primary="450" processor="ARM" endian="little" size="32" variant="v8T" /> <!-- THUMB -->
<constraint primary="452" processor="ARM" endian="little" size="32" variant="v8T" /> <!-- THUMB -->
</constraint>
</opinions>
@@ -0,0 +1,302 @@
# Specification for the ARM Version 4, 4T, 5, 5T, 5E
# The following boolean defines control specific support: T_VARIANT, VERSION_5, VERSION_5E
define endian=$(ENDIAN);
define alignment=2;
define space ram type=ram_space size=4 default;
define space register type=register_space size=4;
define register offset=0x0020 size=4 [ r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 sp lr pc ];
define register offset=0x0060 size=1 [ NG ZR CY OV tmpNG tmpZR tmpCY tmpOV shift_carry TB Q GE1 GE2 GE3 GE4 ];
define register offset=0x0070 size=4 [ cpsr spsr ];
define register offset=0x0080 size=4 [ mult_addr ]; # Special internal register for dealing with multiple stores/loads
define register offset=0x0084 size=4 [ r14_svc r13_svc spsr_svc ];
define register offset=0x0090 size=8 [ mult_dat8 ]; # Special internal register for dealing with multiple stores/loads
define register offset=0x0090 size=16 [ mult_dat16 ]; # Special internal register for dealing with multiple stores/loads
define register offset=0x00A0 size=4 [ fpsr ]; # floating point state register (for FPA10 floating-point accelerator)
define register offset=0x00B0 size=1 [ ISAModeSwitch ]; # generic name for TB ThumbBit - set same as TB
@define FPSCR_N "fpscr[31,1]"
@define FPSCR_Z "fpscr[30,1]"
@define FPSCR_C "fpscr[29,1]"
@define FPSCR_V "fpscr[28,1]"
@if defined(VFPv2) || defined(VFPv3) || defined(SIMD)
define register offset=0x00B0 size=4 [ fpsid fpscr fpexc mvfr0 mvfr1 ];
@endif
define register offset=0x0100 size=10 [ fp0 fp1 fp2 fp3 fp4 fp5 fp6 fp7 ]; # eight 80-bit floating registers
# pseudo-registers for coprocessor calculations
define register offset=0x0200 size=4 [ cr0 cr1 cr2 cr3 cr4 cr5 cr6 cr7 cr8 cr9 cr10 cr11 cr12 cr13 cr14 cr15 ];
# Advanced SIMD and VFP extension registers
@if defined(VFPv2) || defined(VFPv3)
@if ENDIAN == "little"
define register offset=0x0300 size=4 [ s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 s12 s13 s14 s15
s16 s17 s18 s19 s20 s21 s22 s23 s24 s25 s26 s27 s28 s29 s30 s31 ];
@else # ENDIAN == "big"
define register offset=0x0300 size=4 [ s31 s30 s29 s28 s27 s26 s25 s24 s23 s22 s21 s20 s19 s18 s17 s16
s15 s14 s13 s12 s11 s10 s9 s8 s7 s6 s5 s4 s3 s2 s1 s0 ];
@endif # ENDIAN = "big"
@endif # VFPv2 || VFPv3
@if defined(VFPv2)
@if ENDIAN == "little"
define register offset=0x0300 size=8 [ d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 d12 d13 d14 d15 ];
@else # ENDIAN == "big"
define register offset=0x0300 size=8 [ d15 d14 d13 d12 d11 d10 d9 d8 d7 d6 d5 d4 d3 d2 d1 d0 ];
@endif # ENDIAN = "big"
@endif # VFPv2
@if defined(SIMD) || defined(VFPv3)
@if ENDIAN == "little"
define register offset=0x0300 size=8 [ d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 d12 d13 d14 d15
d16 d17 d18 d19 d20 d21 d22 d23 d24 d25 d26 d27 d28 d29 d30 d31 ];
@else # ENDIAN == "big"
define register offset=0x0300 size=8 [ d31 d30 d29 d28 d27 d26 d25 d24 d23 d22 d21 d20 d19 d18 d17 d16
d15 d14 d13 d12 d11 d10 d9 d8 d7 d6 d5 d4 d3 d2 d1 d0 ];
@endif # ENDIAN = "big"
@endif # SIMD || VFPv3
@if defined(SIMD)
@if ENDIAN == "little"
define register offset=0x0300 size=16 [ q0 q1 q2 q3 q4 q5 q6 q7 q8 q9 q10 q11 q12 q13 q14 q15 ];
@else # ENDIAN == "big"
define register offset=0x0300 size=16 [ q15 q14 q13 q12 q11 q10 q9 q8 q7 q6 q5 q4 q3 q2 q1 q0 ];
@endif # ENDIAN = "big"
@endif # SIMD
# Define context bits
# WARNING: when adjusting context keep compiler packing in mind
# and make sure fields do not span a 32-bit boundary before or
# after context packing
define register offset=0x00 size=8 contextreg;
define context contextreg
@ifdef T_VARIANT
TMode = (0,0) # 1 if in Thumb instruction decode mode
T = (0,0) # exact copy (alias!) of TMode
LowBitCodeMode = (0,0) # 1 if low bit of instruction address is set on a branch
ISA_MODE = (0,0) # 1 for Thumb instruction decode mode
@endif
LRset = (1,1) noflow # 1 if the instruction right before was a mov lr,pc
REToverride = (2,2) noflow # 1 if the instruction should be a branch not a return
CALLoverride = (3,3) noflow # 1 if the call should actually be a jump
@if defined(VERSION_6T2) || defined(VERSION_7)
TEEMode = (4,4) # 1 if in ThumbEE mode, changes some instruction behavior, and makes some instructions invalid
condit = (5,13) noflow # both base and shift
cond_mask = (10,13) # base condition
cond_full = (6,9) # full condition
cond_true = (9,9) # true if this condition should be tested for true
cond_base = (6,8) # shift mask for controlling shift
cond_shft = (9,13) # mask and lower bit of it condition field
itmode = (5,5) # true if in ITBlock mode
@endif
# Transient context bits
counter = (14,18) # 0 to 7 counter (for building variable length register lists)
# dreg = (17,21) # D register (attached, for building register lists)
# sreg = (17,21) # S register (attached, for building register lists)
regNum = (19,23) # D register number (see dreg)
counter2 = (24,26) # 0 to 7 counter (for building variable length register lists)
# dreg2 = (25,29) # 2nd D register (attached, for building register lists)
# sreg2 = (25,29) # 2nd S register (attached, for building register lists)
reg2Num = (27,31) # 2nd D register number (see dreg2)
# --- do not allow any field to span 32-bit boundary ---
regInc = (32,33) # Pair register increment
ARMcond = (34,34) # ARM conditional instruction
ARMcondCk = (35,35) # Finished ARM condition check phase
;
define pcodeop coprocessor_function;
define pcodeop coprocessor_function2;
define pcodeop coprocessor_load;
define pcodeop coprocessor_load2;
define pcodeop coprocessor_loadlong;
define pcodeop coprocessor_loadlong2;
define pcodeop coprocessor_moveto;
define pcodeop coprocessor_moveto2;
define pcodeop coprocessor_movefromRt;
define pcodeop coprocessor_movefromRt2;
define pcodeop coprocessor_movefrom2;
define pcodeop coprocessor_store;
define pcodeop coprocessor_store2;
define pcodeop coprocessor_storelong;
define pcodeop coprocessor_storelong2;
define pcodeop software_interrupt;
define pcodeop software_bkpt;
define pcodeop software_udf;
define pcodeop software_hlt;
define pcodeop software_hvc;
define pcodeop software_smc;
# CPS methods (Version 6)
define pcodeop setUserMode;
define pcodeop setFIQMode;
define pcodeop setIRQMode;
define pcodeop setSupervisorMode;
define pcodeop setMonitorMode;
define pcodeop setAbortMode;
define pcodeop setUndefinedMode;
define pcodeop setSystemMode;
define pcodeop enableIRQinterrupts;
define pcodeop enableFIQinterrupts;
define pcodeop enableDataAbortInterrupts;
define pcodeop disableIRQinterrupts;
define pcodeop disableFIQinterrupts;
define pcodeop isFIQinterruptsEnabled;
define pcodeop isIRQinterruptsEnabled;
define pcodeop disableDataAbortInterrupts;
define pcodeop hasExclusiveAccess;
define pcodeop isCurrentModePrivileged;
define pcodeop setThreadModePrivileged;
define pcodeop isThreadMode;
define pcodeop jazelle_branch;
define pcodeop ClearExclusiveLocal;
define pcodeop HintDebug;
define pcodeop DataMemoryBarrier;
define pcodeop DataSynchronizationBarrier;
define pcodeop secureMonitorCall;
define pcodeop WaitForEvent;
define pcodeop WaitForInterrupt;
define pcodeop HintYield;
define pcodeop InstructionSynchronizationBarrier;
define pcodeop HintPreloadData;
define pcodeop HintPreloadDataForWrite;
define pcodeop HintPreloadInstruction;
define pcodeop SignedSaturate;
define pcodeop SignedDoesSaturate;
define pcodeop UnsignedSaturate;
define pcodeop UnsignedDoesSaturate;
define pcodeop Absolute;
define pcodeop ReverseBitOrder;
define pcodeop SendEvent;
define pcodeop setEndianState;
macro affectflags() {
CY = tmpCY; ZR = tmpZR; NG = tmpNG; OV = tmpOV;
}
macro affect_resflags() {
ZR = tmpZR; NG = tmpNG;
}
macro SetThumbMode(value) {
ISAModeSwitch = value;
TB = ISAModeSwitch;
}
#
# simple branch, not inter-working
macro BranchWritePC(addr) {
pc = addr;
}
#
# Interworking branch, ARM<->Thumb
macro BXWritePC(addr) {
SetThumbMode((addr & 0x1) != 0);
local tmp = addr & 0xfffffffe;
pc = tmp;
}
#
# Branch depends on version
macro LoadWritePC(addr) {
@if defined(VERSION_5)
BXWritePC(addr);
@else
BranchWritePC(addr);
@endif
}
# Branch depends on version
macro ALUWritePC(addr) {
@if defined(VERSION_7)
BXWritePC(addr);
@else
BranchWritePC(addr);
@endif
}
@if defined(T_VARIANT)
ItCond: is TMode=1 { }
CheckInIT_CZNO: is TMode=1 { CY = tmpCY; ZR = tmpZR; NG = tmpNG; OV = tmpOV; } # in older, arms always affect flags
CheckInIT_CZN: is TMode=1 { CY = tmpCY; ZR = tmpZR; NG = tmpNG; } # in older, arms always affect flags
CheckInIT_ZN: is TMode=1 { ZR = tmpZR; NG = tmpNG; } # in older, arms always affect flags
@endif
@if defined(VERSION_6T2) || defined(VERSION_7)
# conditionals for instruction following IT Block
thfcc: "eq" is cond_full=0 { local tmp:1 = (ZR!=0); export tmp; }
thfcc: "ne" is cond_full=1 { local tmp:1 = (ZR==0); export tmp; }
thfcc: "cs" is cond_full=2 { local tmp:1 = (CY!=0); export tmp; }
thfcc: "cc" is cond_full=3 { local tmp:1 = (CY==0); export tmp; }
thfcc: "mi" is cond_full=4 { local tmp:1 = (NG!=0); export tmp; }
thfcc: "pl" is cond_full=5 { local tmp:1 = (NG==0); export tmp; }
thfcc: "vs" is cond_full=6 { local tmp:1 = (OV!=0); export tmp; }
thfcc: "vc" is cond_full=7 { local tmp:1 = (OV==0); export tmp; }
thfcc: "hi" is cond_full=8 { local tmp:1 = CY && !ZR; export tmp; }
thfcc: "ls" is cond_full=9 { local tmp:1 = !CY || ZR; export tmp; }
thfcc: "ge" is cond_full=10 { local tmp:1 = (NG == OV); export tmp; }
thfcc: "lt" is cond_full=11 { local tmp:1 = (NG != OV); export tmp; }
thfcc: "gt" is cond_full=12 { local tmp:1 = !ZR && (NG == OV); export tmp; }
thfcc: "le" is cond_full=13 { local tmp:1 = ZR || (NG != OV); export tmp; }
thfcc: "al" is cond_full=14 { local tmp:1 = 1; export tmp; } #can happen
#thfcc: "nv" is cond_full=15 { local tmp:1 = 0; export tmp; } #unpredictable, shouldn't happen
# no ITcondition
ItCond: is TMode=1 & itmode=0 & cond_mask=0 {}
# ITBlock then/else case - the condition being tested is modified by the shift below
ItCond: "."thfcc is TMode=1 & itmode=0 & cond_mask & thfcc [ itmode=1; globalset(inst_next,condit);]
{ if (!thfcc) goto inst_next; }
# last ITBlock then/else case - the condition being tested is modified by the shift below
ItCond: "."thfcc is TMode=1 & itmode=0 & cond_mask=8 & thfcc
{ if (!thfcc) goto inst_next; }
# certain Thumb instructions don't affect all flags in the IT block
CheckInIT_CZNO: is TMode=1 & itmode=1 & cond_mask { } # Do nothing to the flag bits
CheckInIT_CZNO: is TMode=1 & itmode=0 & cond_mask { } # Do nothing to the flag bits
CheckInIT_CZNO: "s" is TMode=1 & itmode=0 & cond_mask=0 { CY = tmpCY; ZR = tmpZR; NG = tmpNG; OV = tmpOV; }
CheckInIT_CZN: is TMode=1 & itmode=1 & cond_mask { } # Do nothing to the flag bits
CheckInIT_CZN: is TMode=1 & itmode=0 & cond_mask { } # Do nothing to the flag bits
CheckInIT_CZN: "s" is TMode=1 & itmode=0 & cond_mask=0 { CY = tmpCY; ZR = tmpZR; NG = tmpNG; }
CheckInIT_ZN: is TMode=1 & itmode=1 & cond_mask { } # Do nothing to the flag bits
CheckInIT_ZN: is TMode=1 & itmode=0 & cond_mask { } # Do nothing to the flag bits
CheckInIT_ZN: "s" is TMode=1 & itmode=0 & cond_mask=0 { ZR = tmpZR; NG = tmpNG; }
:^instruction is itmode=1 & cond_mask=8 & instruction [ condit=0; ] {}
:^instruction is itmode=1 & cond_mask & instruction [ cond_shft=cond_shft << 1; itmode=0; ]{}
@endif # defined(VERSION_6T2) || defined(VERSION_7)
@include "ARMinstructions.sinc"
# THUMB instructions
@ifdef T_VARIANT
@include "ARMTHUMBinstructions.sinc"
@endif
@@ -0,0 +1,5 @@
@define ENDIAN "big"
@include "ARM.sinc"
@@ -0,0 +1,5 @@
@define ENDIAN "little"
@include "ARM.sinc"
@@ -0,0 +1,6 @@
@define ENDIAN "big"
@define T_VARIANT ""
@include "ARM.sinc"
@@ -0,0 +1,6 @@
@define ENDIAN "little"
@define T_VARIANT ""
@include "ARM.sinc"
@@ -0,0 +1,7 @@
@define ENDIAN "big"
@define VERSION_5 ""
@define VERSION_5E ""
@include "ARM.sinc"
@@ -0,0 +1,7 @@
@define ENDIAN "little"
@define VERSION_5 ""
@define VERSION_5E ""
@include "ARM.sinc"
@@ -0,0 +1,9 @@
@define ENDIAN "big"
@define T_VARIANT ""
@define VERSION_5 ""
@define VERSION_5E ""
@include "ARM.sinc"
@@ -0,0 +1,8 @@
@define ENDIAN "little"
@define T_VARIANT ""
@define VERSION_5 ""
@define VERSION_5E ""
@include "ARM.sinc"
@@ -0,0 +1,12 @@
@define ENDIAN "big"
@define T_VARIANT ""
@define VERSION_5 ""
@define VERSION_5E ""
@define VERSION_6 ""
@define VERSION_6K ""
@define VERSION_6T2 ""
@define VFPv2 ""
@include "ARM.sinc"
@@ -0,0 +1,12 @@
@define ENDIAN "little"
@define T_VARIANT ""
@define VERSION_5 ""
@define VERSION_5E ""
@define VERSION_6 ""
@define VERSION_6K ""
@define VERSION_6T2 ""
@define VFPv2 ""
@include "ARM.sinc"
@@ -0,0 +1,16 @@
@define ENDIAN "big"
@define T_VARIANT ""
@define VERSION_5 ""
@define VERSION_5E ""
@define VERSION_6 ""
@define VERSION_6K ""
@define VERSION_6T2 ""
@define VERSION_7 ""
@define VERSION_7M ""
@define SIMD ""
@define VFPv3 ""
@define VFPv4 ""
@include "ARM.sinc"
@@ -0,0 +1,16 @@
@define ENDIAN "little"
@define T_VARIANT ""
@define VERSION_5 ""
@define VERSION_5E ""
@define VERSION_6 ""
@define VERSION_6K ""
@define VERSION_6T2 ""
@define VERSION_7 ""
@define VERSION_7M ""
@define SIMD ""
@define VFPv3 ""
@define VFPv4 ""
@include "ARM.sinc"
@@ -0,0 +1,17 @@
@define ENDIAN "big"
@define T_VARIANT ""
@define VERSION_5 ""
@define VERSION_5E ""
@define VERSION_6 ""
@define VERSION_6K ""
@define VERSION_6T2 ""
@define VERSION_7 ""
@define VERSION_7M ""
@define VERSION_8 ""
@define SIMD ""
@define VFPv3 ""
@define VFPv4 ""
@include "ARM.sinc"
@@ -0,0 +1,17 @@
@define ENDIAN "little"
@define T_VARIANT ""
@define VERSION_5 ""
@define VERSION_5E ""
@define VERSION_6 ""
@define VERSION_6K ""
@define VERSION_6T2 ""
@define VERSION_7 ""
@define VERSION_7M ""
@define VERSION_8 ""
@define SIMD ""
@define VFPv3 ""
@define VFPv4 ""
@include "ARM.sinc"
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<processor_spec>
<properties>
<property key="addressesDoNotAppearDirectlyInCode" value="true"/>
<property key="allowOffcutReferencesToFunctionStarts" value="true"/>
<property key="useNewFunctionStackAnalysis" value="true"/>
<property key="enableContiguousFunctionsOnly" value="false"/>
<property key="emulateInstructionStateModifierClass" value="ghidra.program.emulation.ARMEmulateInstructionStateModifier"/>
</properties>
<programcounter register="pc"/>
<context_data>
<context_set space="ram">
<set name="TMode" val="1" description="0 for ARM 32-bit, 1 for THUMB 16-bit"/>
<set name="LRset" val="0" description="0 lr reg not set, 1 for LR set, affects BX as a call"/>
</context_set>
<tracked_set space="ram">
<set name="spsr" val="0"/>
</tracked_set>
</context_data>
<default_symbols>
<symbol name="MasterStackPointer" address="ram:0x0" entry="false" type="code_ptr"/>
<symbol name="Reset" address="ram:0x4" entry="true" type="code_ptr"/>
<symbol name="NMI" address="ram:0x8" entry="true" type="code_ptr"/>
<symbol name="HardFault" address="ram:0xC" entry="true" type="code_ptr"/>
<symbol name="MemManage" address="ram:0x10" entry="true" type="code_ptr"/>
<symbol name="BusFault" address="ram:0x14" entry="true" type="code_ptr"/>
<symbol name="UsageFault" address="ram:0x18" entry="true" type="code_ptr"/>
<symbol name="Reserved1" address="ram:0x1c" entry="true" type="code_ptr"/>
<symbol name="Reserved2" address="ram:0x20" entry="true" type="code_ptr"/>
<symbol name="Reserved3" address="ram:0x24" entry="true" type="code_ptr"/>
<symbol name="Reserved4" address="ram:0x28" entry="true" type="code_ptr"/>
<symbol name="SVCall" address="ram:0x2c" entry="true" type="code_ptr"/>
<symbol name="Reserved5" address="ram:0x30" entry="true" type="code_ptr"/>
<symbol name="Reserved6" address="ram:0x34" entry="true" type="code_ptr"/>
<symbol name="PendSV" address="ram:0x38" entry="true" type="code_ptr"/>
<symbol name="SysTick" address="ram:0x3C" entry="true" type="code_ptr"/>
<symbol name="IRQ" address="ram:0x40" entry="true" type="code_ptr"/>
</default_symbols>
</processor_spec>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,209 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This arm cspec split from the main arm.cspec.
The difference is no floating point registers for
older arm variants (pre-v7)
-->
<compiler_spec>
<!--
Assumes Procedure Call Standard for the ARM Architecture (AAPCS) Applies.
-->
<data_organization> <!-- These tags were generated with gcc 4.2.4 -->
<absolute_max_alignment value="0" />
<machine_alignment value="2" />
<default_alignment value="1" />
<default_pointer_alignment value="4" />
<pointer_size value="4" />
<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"/>
</global>
<stackpointer register="sp" space="ram"/>
<funcptr align="2"/> <!-- Function pointers are word aligned and leastsig bit may encode otherstuff -->
<default_proto>
<prototype name="__stdcall" extrapop="0" stackshift="0">
<input>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="r0"/>
</pentry>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="r1"/>
</pentry>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="r2"/>
</pentry>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="r3"/>
</pentry>
<pentry minsize="1" maxsize="500" align="4">
<addr offset="0" space="stack"/>
</pentry>
</input>
<output>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="r0"/>
</pentry>
<pentry minsize="5" maxsize="8">
<addr space="join" piece1="r1" piece2="r0"/>
</pentry>
</output>
<unaffected>
<register name="r4"/>
<register name="r5"/>
<register name="r6"/>
<register name="r7"/>
<register name="r8"/>
<register name="r9"/>
<register name="r10"/>
<register name="r11"/>
<register name="sp"/>
</unaffected>
<killedbycall>
<register name="r1"/>
</killedbycall>
</prototype>
</default_proto>
<callfixup name="switch8_r3">
<target name="switch8_r3"/>
<pcode>
<body><![CDATA[
tmpptr = lr - 1;
tblsize = *:1 tmpptr;
r12 = zext(tblsize);
inbounds = r3 < r12;
if (!inbounds) goto <next1>;
offset = *:1 (lr + r3);
r3 = zext(offset);
<next1>
if (inbounds) goto <next2>;
offset = *:1 (lr + r12);
r3 = zext(offset);
<next2>
r3 = r3 * 2;
r12 = lr + r3;
ISAModeSwitch = (r12 & 1) != 1;
TB = ISAModeSwitch;
pc = r12 & 0xfffffffe;
goto [pc];
]]></body>
</pcode>
</callfixup>
<callfixup name="switch8_r0">
<target name="__gnu_thumb1_case_uqi"/>
<target name="switch8_r0"/>
<pcode>
<body><![CDATA[
tmpptr = lr & 0xfffffffe;
offset = *:1 (tmpptr + r0);
lr = lr + 2 * zext(offset);
ISAModeSwitch = (lr & 1) != 0;
TB = ISAModeSwitch;
pc = lr & 0xfffffffe;
goto [pc];
]]></body>
</pcode>
</callfixup>
<callfixup name="switchS8_r0">
<target name="__gnu_thumb1_case_sqi"/>
<target name="switchS8_r0"/>
<pcode>
<body><![CDATA[
tmpptr = lr & 0xfffffffe;
offset = *:1 (tmpptr + r0);
lr = lr + 2 * sext(offset);
ISAModeSwitch = (lr & 1) != 0;
TB = ISAModeSwitch;
pc = lr & 0xfffffffe;
goto [pc];
]]></body>
</pcode>
</callfixup>
<callfixup name="switch16_shi_r0">
<target name="__gnu_thumb1_case_shi"/>
<target name="switch16_shi_r0"/>
<pcode>
<body><![CDATA[
tmpptr = lr & 0xfffffffe;
index = r0 * 2;
offset = *:2 (tmpptr + index);
lr = lr + 2 * sext(offset);
ISAModeSwitch = (lr & 1) != 0;
TB = ISAModeSwitch;
pc = lr & 0xfffffffe;
goto [pc];
]]></body>
</pcode>
</callfixup>
<callfixup name="switch16_uhi_r0">
<target name="__gnu_thumb1_case_uhi"/>
<target name="switch16_shi_r0"/>
<pcode>
<body><![CDATA[
tmpptr = lr & 0xfffffffe;
index = r0 * 2;
offset = *:2 (tmpptr + index);
lr = lr + 2 * zext(offset);
ISAModeSwitch = (lr & 1) != 0;
TB = ISAModeSwitch;
pc = lr & 0xfffffffe;
goto [pc];
]]></body>
</pcode>
</callfixup>
<callfixup name="switch32_si_r0">
<target name="__gnu_thumb1_case_si"/>
<target name="switch32_si_r0"/>
<pcode>
<body><![CDATA[
tmpptr = (lr + 2) & 0xfffffffc;
index = r0 * 4;
offset = *:4 (tmpptr + index);
offset = offset * 4;
lr = lr + offset;
ISAModeSwitch = (lr & 1) != 0;
TB = ISAModeSwitch;
pc = lr & 0xfffffffe;
goto [pc];
]]></body>
</pcode>
</callfixup>
</compiler_spec>
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<processor_spec>
<properties>
<property key="addressesDoNotAppearDirectlyInCode" value="true"/>
<property key="allowOffcutReferencesToFunctionStarts" value="true"/>
<property key="useNewFunctionStackAnalysis" value="true"/>
<property key="enableSharedReturnAnalysis" value="false"/>
<property key="enableContiguousFunctionsOnly" value="false"/>
<property key="emulateInstructionStateModifierClass" value="ghidra.program.emulation.ARMEmulateInstructionStateModifier"/>
</properties>
<programcounter register="pc"/>
<context_data>
<context_set space="ram">
<set name="LRset" val="0" description="0 lr reg not set, 1 for LR set, affects BX as a call"/>
</context_set>
<tracked_set space="ram">
<set name="spsr" val="0"/>
</tracked_set>
</context_data>
<default_symbols>
<symbol name="Reset" address="ram:0x0" entry="true"/>
<symbol name="UndefinedInstruction" address="ram:0x4" entry="true"/>
<symbol name="SupervisorCall" address="ram:0x8" entry="true"/>
<symbol name="PrefetchAbort" address="ram:0xC" entry="true"/>
<symbol name="DataAbort" address="ram:0x10" entry="true"/>
<symbol name="IRQ" address="ram:0x18" entry="true"/>
<symbol name="FIQ" address="ram:0x1c" entry="true"/>
<symbol name="H_Reset" address="ram:0xFFFF0000" entry="true"/>
<symbol name="H_UndefinedInstruction" address="ram:0xFFFF0004" entry="true"/>
<symbol name="H_SupervisorCall" address="ram:0xFFFF0008" entry="true"/>
<symbol name="H_PrefetchAbort" address="ram:0xFFFF000C" entry="true"/>
<symbol name="H_DataAbort" address="ram:0xFFFF0010" entry="true"/>
<symbol name="H_IRQ" address="ram:0xFFFF0018" entry="true"/>
<symbol name="H_FIQ" address="ram:0xFFFF001c" entry="true"/>
</default_symbols>
</processor_spec>
@@ -0,0 +1,131 @@
<?xml version="1.0" encoding="UTF-8"?>
<compiler_spec>
<!-- Copied from ARM.cspec and modified... See: https://docs.microsoft.com/en-us/cpp/build/overview-of-arm-abi-conventions?view=vs-2019 -->
<data_organization>
<absolute_max_alignment value="0" />
<machine_alignment value="2" />
<default_alignment value="1" />
<default_pointer_alignment value="4" />
<pointer_size value="4" />
<wchar_size value="2" />
<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>
<bitfield_packing>
<use_MS_convention value="true"/>
</bitfield_packing>
</data_organization>
<global>
<range space="ram"/>
</global>
<stackpointer register="sp" space="ram"/>
<funcptr align="2"/> <!-- Function pointers are word aligned and leastsig bit may encode otherstuff -->
<default_proto>
<prototype name="__stdcall" extrapop="0" stackshift="0">
<input>
<!-- we cannot accurately model the allocation scheme when parameters are larger than 4 bytes -->
<pentry minsize="1" maxsize="4" metatype="float">
<register name="s0"/>
</pentry>
<pentry minsize="1" maxsize="4" metatype="float">
<register name="s1"/>
</pentry>
<pentry minsize="1" maxsize="4" metatype="float">
<register name="s2"/>
</pentry>
<pentry minsize="1" maxsize="4" metatype="float">
<register name="s3"/>
</pentry>
<pentry minsize="1" maxsize="4" metatype="float">
<register name="s4"/>
</pentry>
<pentry minsize="1" maxsize="4" metatype="float">
<register name="s5"/>
</pentry>
<pentry minsize="1" maxsize="4" metatype="float">
<register name="s6"/>
</pentry>
<pentry minsize="1" maxsize="4" metatype="float">
<register name="s7"/>
</pentry>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="r0"/>
</pentry>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="r1"/>
</pentry>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="r2"/>
</pentry>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="r3"/>
</pentry>
<pentry minsize="1" maxsize="500" align="4">
<addr offset="0" space="stack"/>
</pentry>
</input>
<output>
<pentry minsize="1" maxsize="16" metatype="float">
<register name="q0"/>
</pentry>
<pentry minsize="1" maxsize="4" extension="inttype">
<register name="r0"/>
</pentry>
<pentry minsize="5" maxsize="8">
<addr space="join" piece1="r1" piece2="r0"/>
</pentry>
</output>
<unaffected>
<register name="r4"/>
<register name="r5"/>
<register name="r6"/>
<register name="r7"/>
<register name="r8"/>
<register name="r9"/>
<register name="r10"/>
<register name="r11"/>
<register name="q4"/>
<register name="q5"/>
<register name="q6"/>
<register name="q7"/>
<register name="sp"/>
<register name="lr"/>
<register name="pc"/>
</unaffected>
<killedbycall>
<register name="r0"/>
<register name="r1"/>
<register name="r2"/>
<register name="r3"/>
<register name="r12"/>
<register name="q0"/>
<register name="q1"/>
<register name="q2"/>
<register name="q3"/>
<register name="q8"/>
<register name="q9"/>
<register name="q10"/>
<register name="q11"/>
<register name="q12"/>
<register name="q13"/>
<register name="q14"/>
<register name="q15"/>
</killedbycall>
</prototype>
</default_proto>
</compiler_spec>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,14 @@
<dwarf>
<register_mappings>
<register_mapping dwarf="0" ghidra="r0" auto_count="13"/> <!-- r0..r12 -->
<register_mapping dwarf="13" ghidra="sp" stackpointer="true"/>
<register_mapping dwarf="14" ghidra="lr"/>
<register_mapping dwarf="15" ghidra="pc"/>
<register_mapping dwarf="16" ghidra="fpsr"/>
<register_mapping dwarf="17" ghidra="cpsr"/>
<register_mapping dwarf="256" ghidra="d0" auto_count="32"/> <!-- d0..d31 -->
<register_mapping dwarf="64" ghidra="s0" auto_count="32"/> <!-- s0..s31 -->
</register_mappings>
<call_frame_cfa value="0"/>
<use_formal_parameter_storage/>
</dwarf>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8"?>
<processor_spec>
<properties>
<property key="addressesDoNotAppearDirectlyInCode" value="true"/>
<property key="allowOffcutReferencesToFunctionStarts" value="true"/>
<property key="useNewFunctionStackAnalysis" value="true"/>
<property key="enableContiguousFunctionsOnly" value="false"/>
<property key="emulateInstructionStateModifierClass" value="ghidra.program.emulation.ARMEmulateInstructionStateModifier"/>
<property key="assemblyRating:ARM:BE:32:v7" value="PLATINUM"/>
<property key="assemblyRating:ARM:LE:32:v7" value="PLATINUM"/>
</properties>
<programcounter register="pc"/>
<context_data>
<context_set space="ram">
<set name="TMode" val="0" description="0 for ARM 32-bit, 1 for THUMB 16-bit"/>
<set name="LRset" val="0" description="0 lr reg not set, 1 for LR set, affects BX as a call"/>
</context_set>
<tracked_set space="ram">
<set name="spsr" val="0"/>
</tracked_set>
</context_data>
<default_symbols>
<symbol name="Reset" address="ram:0x0" entry="true"/>
<symbol name="UndefinedInstruction" address="ram:0x4" entry="true"/>
<symbol name="SupervisorCall" address="ram:0x8" entry="true"/>
<symbol name="PrefetchAbort" address="ram:0xC" entry="true"/>
<symbol name="DataAbort" address="ram:0x10" entry="true"/>
<symbol name="NotUsed" address="ram:0x14" entry="true"/>
<symbol name="IRQ" address="ram:0x18" entry="true"/>
<symbol name="FIQ" address="ram:0x1c" entry="true"/>
<symbol name="H_Reset" address="ram:0xFFFF0000" entry="true"/>
<symbol name="H_UndefinedInstruction" address="ram:0xFFFF0004" entry="true"/>
<symbol name="H_SupervisorCall" address="ram:0xFFFF0008" entry="true"/>
<symbol name="H_PrefetchAbort" address="ram:0xFFFF000C" entry="true"/>
<symbol name="H_DataAbort" address="ram:0xFFFF0010" entry="true"/>
<symbol name="H_NotUsed" address="ram:0xFFFF0014" entry="true"/>
<symbol name="H_IRQ" address="ram:0xFFFF0018" entry="true"/>
<symbol name="H_FIQ" address="ram:0xFFFF001c" entry="true"/>
</default_symbols>
<register_data>
<register name="q0" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q1" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q2" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q3" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q4" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q5" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q6" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q7" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q8" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q9" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q10" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q11" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q12" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q13" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q14" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q15" group="NEON" vector_lane_sizes="1,2,4"/>
</register_data>
</processor_spec>
@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<processor_spec>
<!-- THIS PSPEC IS A COPY OF ARMt.pspec AND ONLY DIFFERS WITH ENABLEMENT OF THUMB AS DEFAULT CONTEXT -->
<properties>
<property key="addressesDoNotAppearDirectlyInCode" value="true"/>
<property key="allowOffcutReferencesToFunctionStarts" value="true"/>
<property key="useNewFunctionStackAnalysis" value="true"/>
<property key="enableContiguousFunctionsOnly" value="false"/>
<property key="emulateInstructionStateModifierClass" value="ghidra.program.emulation.ARMEmulateInstructionStateModifier"/>
<property key="assemblyRating:ARM:BE:32:v7" value="PLATINUM"/>
<property key="assemblyRating:ARM:LE:32:v7" value="PLATINUM"/>
</properties>
<programcounter register="pc"/>
<context_data>
<context_set space="ram">
<set name="TMode" val="1" description="0 for ARM 32-bit, 1 for THUMB 16-bit"/>
<set name="LRset" val="0" description="0 lr reg not set, 1 for LR set, affects BX as a call"/>
</context_set>
<tracked_set space="ram">
<set name="spsr" val="0"/>
</tracked_set>
</context_data>
<default_symbols>
<symbol name="Reset" address="ram:0x0" entry="true"/>
<symbol name="UndefinedInstruction" address="ram:0x4" entry="true"/>
<symbol name="SupervisorCall" address="ram:0x8" entry="true"/>
<symbol name="PrefetchAbort" address="ram:0xC" entry="true"/>
<symbol name="DataAbort" address="ram:0x10" entry="true"/>
<symbol name="NotUsed" address="ram:0x14" entry="true"/>
<symbol name="IRQ" address="ram:0x18" entry="true"/>
<symbol name="FIQ" address="ram:0x1c" entry="true"/>
<symbol name="H_Reset" address="ram:0xFFFF0000" entry="true"/>
<symbol name="H_UndefinedInstruction" address="ram:0xFFFF0004" entry="true"/>
<symbol name="H_SupervisorCall" address="ram:0xFFFF0008" entry="true"/>
<symbol name="H_PrefetchAbort" address="ram:0xFFFF000C" entry="true"/>
<symbol name="H_DataAbort" address="ram:0xFFFF0010" entry="true"/>
<symbol name="H_NotUsed" address="ram:0xFFFF0014" entry="true"/>
<symbol name="H_IRQ" address="ram:0xFFFF0018" entry="true"/>
<symbol name="H_FIQ" address="ram:0xFFFF001c" entry="true"/>
</default_symbols>
<register_data>
<register name="q0" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q1" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q2" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q3" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q4" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q5" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q6" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q7" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q8" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q9" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q10" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q11" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q12" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q13" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q14" group="NEON" vector_lane_sizes="1,2,4"/>
<register name="q15" group="NEON" vector_lane_sizes="1,2,4"/>
</register_data>
</processor_spec>
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<processor_spec>
<properties>
<property key="addressesDoNotAppearDirectlyInCode" value="true"/>
<property key="allowOffcutReferencesToFunctionStarts" value="true"/>
<property key="useNewFunctionStackAnalysis" value="true"/>
<property key="enableSharedReturnAnalysis" value="false"/>
<property key="enableContiguousFunctionsOnly" value="false"/>
<property key="emulateInstructionStateModifierClass" value="ghidra.program.emulation.ARMEmulateInstructionStateModifier"/>
</properties>
<programcounter register="pc"/>
<context_data>
<context_set space="ram">
<set name="TMode" val="0" description="0 for ARM 32-bit, 1 for THUMB 16-bit"/>
<set name="LRset" val="0" description="0 lr reg not set, 1 for LR set, affects BX as a call"/>
</context_set>
<tracked_set space="ram">
<set name="spsr" val="0"/>
</tracked_set>
</context_data>
<default_symbols>
<symbol name="Reset" address="ram:0x0" entry="true"/>
<symbol name="UndefinedInstruction" address="ram:0x4" entry="true"/>
<symbol name="SupervisorCall" address="ram:0x8" entry="true"/>
<symbol name="PrefetchAbort" address="ram:0xC" entry="true"/>
<symbol name="DataAbort" address="ram:0x10" entry="true"/>
<symbol name="NotUsed" address="ram:0x14" entry="true"/>
<symbol name="IRQ" address="ram:0x18" entry="true"/>
<symbol name="FIQ" address="ram:0x1c" entry="true"/>
<symbol name="H_Reset" address="ram:0xFFFF0000" entry="true"/>
<symbol name="H_UndefinedInstruction" address="ram:0xFFFF0004" entry="true"/>
<symbol name="H_SupervisorCall" address="ram:0xFFFF0008" entry="true"/>
<symbol name="H_PrefetchAbort" address="ram:0xFFFF000C" entry="true"/>
<symbol name="H_DataAbort" address="ram:0xFFFF0010" entry="true"/>
<symbol name="H_NotUsed" address="ram:0xFFFF0014" entry="true"/>
<symbol name="H_IRQ" address="ram:0xFFFF0018" entry="true"/>
<symbol name="H_FIQ" address="ram:0xFFFF001c" entry="true"/>
</default_symbols>
</processor_spec>
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<processor_spec>
<properties>
<property key="addressesDoNotAppearDirectlyInCode" value="true"/>
<property key="allowOffcutReferencesToFunctionStarts" value="true"/>
<property key="useNewFunctionStackAnalysis" value="true"/>
<property key="enableContiguousFunctionsOnly" value="false"/>
<property key="emulateInstructionStateModifierClass" value="ghidra.program.emulation.ARMEmulateInstructionStateModifier"/>
<property key="assemblyRating:ARM:BE:32:v7" value="PLATINUM"/>
<property key="assemblyRating:ARM:LE:32:v7" value="PLATINUM"/>
</properties>
<programcounter register="pc"/>
<context_data>
<context_set space="ram">
<set name="TMode" val="0" description="0 for ARM 32-bit, 1 for THUMB 16-bit"/>
<set name="LRset" val="0" description="0 lr reg not set, 1 for LR set, affects BX as a call"/>
</context_set>
<tracked_set space="ram">
<set name="spsr" val="0"/>
</tracked_set>
</context_data>
<default_symbols>
<symbol name="Reset" address="ram:0x0" entry="true"/>
<symbol name="UndefinedInstruction" address="ram:0x4" entry="true"/>
<symbol name="SupervisorCall" address="ram:0x8" entry="true"/>
<symbol name="PrefetchAbort" address="ram:0xC" entry="true"/>
<symbol name="DataAbort" address="ram:0x10" entry="true"/>
<symbol name="NotUsed" address="ram:0x14" entry="true"/>
<symbol name="IRQ" address="ram:0x18" entry="true"/>
<symbol name="FIQ" address="ram:0x1c" entry="true"/>
<symbol name="H_Reset" address="ram:0xFFFF0000" entry="true"/>
<symbol name="H_UndefinedInstruction" address="ram:0xFFFF0004" entry="true"/>
<symbol name="H_SupervisorCall" address="ram:0xFFFF0008" entry="true"/>
<symbol name="H_PrefetchAbort" address="ram:0xFFFF000C" entry="true"/>
<symbol name="H_DataAbort" address="ram:0xFFFF0010" entry="true"/>
<symbol name="H_NotUsed" address="ram:0xFFFF0014" entry="true"/>
<symbol name="H_IRQ" address="ram:0xFFFF0018" entry="true"/>
<symbol name="H_FIQ" address="ram:0xFFFF001c" entry="true"/>
</default_symbols>
</processor_spec>

Some files were not shown because too many files have changed in this diff Show More