mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-10 14:11:59 +00:00
Added ARC4 CPU support
This commit is contained in:
parent
568ebd45ef
commit
5e299be862
29
Ghidra/Processors/ARC4/LICENSE.txt
Normal file
29
Ghidra/Processors/ARC4/LICENSE.txt
Normal file
@ -0,0 +1,29 @@
|
||||
Copyright (c) 2023, Johns Hopkins University Applied Physics Laboratory
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
0
Ghidra/Processors/ARC4/Module.manifest
Normal file
0
Ghidra/Processors/ARC4/Module.manifest
Normal file
56
Ghidra/Processors/ARC4/add.s
Normal file
56
Ghidra/Processors/ARC4/add.s
Normal file
@ -0,0 +1,56 @@
|
||||
; Copyright 2023 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
; Authors: Dan Genin and Tommy Johnson
|
||||
|
||||
add r2, 0, 0
|
||||
add r3, 1, 1
|
||||
add r4, 2, 2
|
||||
add r6, 3, 3
|
||||
add r0, r1, r5
|
||||
nop
|
||||
add ilink1, 4, 4
|
||||
add blink, 5, 5
|
||||
add sp, 6, 6
|
||||
add r1,r2,32
|
||||
add r3,r4,32
|
||||
add r5,r6,32
|
||||
add r1,ilink1,32
|
||||
add r1,blink,32
|
||||
add r1,sp,32
|
||||
add fp,sp,sp
|
||||
add sp,r1,sp
|
||||
add r1,r1,32
|
||||
add r1,r1,32
|
||||
add r1,r1,0x1FFFFFFF
|
||||
add 0x1FFFFFFF,r1,r2
|
||||
|
||||
ADD r1,r2,r3
|
||||
ADD.NZ r1,r2,r3
|
||||
ADD.F r1,r2,r3
|
||||
ADD.NZ.F r1,r2,r3
|
||||
ADD r1,r2,34
|
||||
ADD.F r1,r2,34
|
||||
ADD r1,34,r2
|
||||
ADD r1,255,255
|
||||
ADD.F 0,r1,r2
|
||||
ADD.F 0,r1,34
|
||||
ADD.F 0,34,r1
|
||||
ADD 0,0,0
|
||||
ADD r3,1,2
|
||||
ADD.F r3,1,2
|
||||
;; A is shimmflags
|
||||
.WORD 0x47c08500
|
||||
;; A is limm
|
||||
.WORD 0x47a08500
|
||||
;; register register
|
||||
;; conditional
|
||||
;; setting flags
|
||||
;;conditional and conditionally set flags
|
||||
;;register immediate
|
||||
;;immediate register
|
||||
;;immediate immediate (shimms MUST match)
|
||||
;;test
|
||||
;;test with immediate
|
||||
;;test with immediate
|
||||
;;null instruction, NOP
|
||||
|
||||
|
42
Ghidra/Processors/ARC4/branch.s
Normal file
42
Ghidra/Processors/ARC4/branch.s
Normal file
@ -0,0 +1,42 @@
|
||||
; Copyright 2023 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
; Authors: Dan Genin and Tommy Johnson
|
||||
|
||||
mov r0, 0
|
||||
mov r1, 1
|
||||
|
||||
# NOTE: Nested delay slot fails to disassemble in Ghidra but is permitted by the assembler (actual results TBD).
|
||||
add r0,r1,r0
|
||||
b.d foo
|
||||
b.d foo
|
||||
add r0,r1,r0 ; not executed
|
||||
foo: sub r0,r1,r0 ; executed twice?
|
||||
add r0,r1,r0
|
||||
j blink
|
||||
|
||||
sub.f 0,r1,r2
|
||||
bnz.jd bar
|
||||
sub r0,r0,r0
|
||||
bar:
|
||||
|
||||
|
||||
# inst 1 j.d r0
|
||||
# inst 2 j.d r1 <-- inst 1 delay slot
|
||||
# inst 3 mov r1,0 <-- inst 2 delay slot
|
||||
|
||||
# ...
|
||||
|
||||
# r0: inst 10 mov r2,0
|
||||
# inst 11 j.d
|
||||
|
||||
# ...
|
||||
|
||||
# r1: inst 20 mov r3, 0
|
||||
# inst 21 j.d
|
||||
|
||||
# t=0 t=1 t=2 t=3
|
||||
#j.d r0 fetch PC=r0 NOP NOP
|
||||
#j.d r1 fetch PC=r1 NOP
|
||||
#mov r2,0 fetch op fetch ..
|
||||
#mov r3,0 fetch
|
||||
|
||||
|
11
Ghidra/Processors/ARC4/build.gradle
Normal file
11
Ghidra/Processors/ARC4/build.gradle
Normal file
@ -0,0 +1,11 @@
|
||||
apply from: "$rootProject.projectDir/gradle/javaProject.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/javaTestProject.gradle"
|
||||
apply from: "$rootProject.projectDir/gradle/processorProject.gradle"
|
||||
apply plugin: 'eclipse'
|
||||
eclipse.project.name = 'Processors ARC4'
|
||||
|
||||
|
||||
dependencies {
|
||||
compile project(':Base')
|
||||
}
|
||||
|
4
Ghidra/Processors/ARC4/build_test.sh
Executable file
4
Ghidra/Processors/ARC4/build_test.sh
Executable file
@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
~/other_projects/arc4-toolchain-20100305-x86/usr/local/arc/arc-elf32/bin/as test.s -o test.o
|
||||
~/other_projects/arc4-toolchain-20100305-x86/usr/local/arc/arc-elf32/bin/ld test.o -o test
|
||||
|
32
Ghidra/Processors/ARC4/certification.manifest
Normal file
32
Ghidra/Processors/ARC4/certification.manifest
Normal file
@ -0,0 +1,32 @@
|
||||
##VERSION: 2.0
|
||||
Module.manifest||GHIDRA||||END|
|
||||
build.gradle||GHIDRA||||END|
|
||||
data/languages/old/ToyV00BE64.lang||GHIDRA||||END|
|
||||
data/languages/old/ToyV0BE64.trans||GHIDRA||||END|
|
||||
data/languages/old/ToyV0LE64.lang||GHIDRA||||END|
|
||||
data/languages/old/ToyV0LE64.trans||GHIDRA||||END|
|
||||
data/languages/old/v01stuff/toy.cspec||GHIDRA|exclude|||END|
|
||||
data/languages/old/v01stuff/toy.ldefs_v01||GHIDRA|exclude|||END|
|
||||
data/languages/old/v01stuff/toy.sinc||GHIDRA|exclude|||END|
|
||||
data/languages/old/v01stuff/toy64.cspec||GHIDRA|exclude|||END|
|
||||
data/languages/old/v01stuff/toyInstructions.sinc||GHIDRA|exclude|||END|
|
||||
data/languages/old/v01stuff/toyPosStack.cspec||GHIDRA|exclude|||END|
|
||||
data/languages/toy.cspec||GHIDRA||||END|
|
||||
data/languages/toy.ldefs||GHIDRA||||END|
|
||||
data/languages/toy.pspec||GHIDRA||reviewed||END|
|
||||
data/languages/toy.sinc||GHIDRA||||END|
|
||||
data/languages/toy64.cspec||GHIDRA||||END|
|
||||
data/languages/toy64_be.slaspec||GHIDRA||reviewed||END|
|
||||
data/languages/toy64_le.slaspec||GHIDRA||reviewed||END|
|
||||
data/languages/toyInstructions.sinc||GHIDRA||||END|
|
||||
data/languages/toyPosStack.cspec||GHIDRA||||END|
|
||||
data/languages/toy_be.slaspec||GHIDRA||||END|
|
||||
data/languages/toy_be_posStack.slaspec||GHIDRA||||END|
|
||||
data/languages/toy_builder.sinc||GHIDRA||||END|
|
||||
data/languages/toy_builder_be.slaspec||GHIDRA||||END|
|
||||
data/languages/toy_builder_be_align2.slaspec||GHIDRA||reviewed||END|
|
||||
data/languages/toy_builder_le.slaspec||GHIDRA||||END|
|
||||
data/languages/toy_builder_le_align2.slaspec||GHIDRA||reviewed||END|
|
||||
data/languages/toy_le.slaspec||GHIDRA||||END|
|
||||
data/languages/toy_wsz_be.slaspec||GHIDRA||reviewed||END|
|
||||
data/languages/toy_wsz_le.slaspec||GHIDRA||reviewed||END|
|
74
Ghidra/Processors/ARC4/data/languages/ARC4.cspec
Normal file
74
Ghidra/Processors/ARC4/data/languages/ARC4.cspec
Normal file
@ -0,0 +1,74 @@
|
||||
<!-- Copyright 2023 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
Authors: Dan Genin and Tommy Johnson
|
||||
-->
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<compiler_spec>
|
||||
<global>
|
||||
<range space="ram"/>
|
||||
</global>
|
||||
<stackpointer register="sp" space="ram"/>
|
||||
<default_proto>
|
||||
<prototype name="__stdcall" extrapop="0" stackshift="0">
|
||||
<input>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="r0"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="r1"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="r2"/>
|
||||
</pentry>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="r3"/>
|
||||
</pentry>
|
||||
<!--pentry minsize="1" maxsize="4">
|
||||
<register name="r4"/>
|
||||
</pentry-->
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="0" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="r0"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<varnode space="ram" offset="0" size="4"/>
|
||||
<register name="sp"/>
|
||||
<register name="fp"/>
|
||||
<register name="blink"/>
|
||||
<register name="r13"/>
|
||||
<register name="r14"/>
|
||||
<register name="r15"/>
|
||||
<register name="r16"/>
|
||||
<register name="r17"/>
|
||||
<register name="r18"/>
|
||||
<register name="r19"/>
|
||||
<register name="r20"/>
|
||||
</unaffected>
|
||||
</prototype>
|
||||
</default_proto>
|
||||
|
||||
<!-- <prototype name="__stackcall" extrapop="unknown" stackshift="4">
|
||||
<input pointermax="16">
|
||||
<pentry minsize="1" maxsize="500" align="4">
|
||||
<addr offset="0" space="stack"/>
|
||||
</pentry>
|
||||
</input>
|
||||
<output>
|
||||
<pentry minsize="1" maxsize="4">
|
||||
<register name="r0"/>
|
||||
</pentry>
|
||||
</output>
|
||||
<unaffected>
|
||||
<varnode space="ram" offset="0" size="4"/>
|
||||
<register name="sp"/>
|
||||
<register name="blink"/>
|
||||
</unaffected>
|
||||
</prototype>
|
||||
-->
|
||||
</compiler_spec>
|
18
Ghidra/Processors/ARC4/data/languages/ARC4.ldefs
Normal file
18
Ghidra/Processors/ARC4/data/languages/ARC4.ldefs
Normal file
@ -0,0 +1,18 @@
|
||||
<!-- Copyright 2023 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
Authors: Dan Genin and Tommy Johnson
|
||||
-->
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<language_definitions>
|
||||
<language processor="ARC4"
|
||||
endian="little"
|
||||
size="32"
|
||||
variant="default"
|
||||
version="1.0"
|
||||
slafile="ARC4_le.sla"
|
||||
processorspec="ARC4.pspec"
|
||||
id="ARC4:BE:32:default">
|
||||
<description>ARC4 32 bit little-endian</description>
|
||||
<compiler name="default" spec="ARC4.cspec" id="default"/>
|
||||
</language>
|
||||
</language_definitions>
|
9
Ghidra/Processors/ARC4/data/languages/ARC4.pspec
Normal file
9
Ghidra/Processors/ARC4/data/languages/ARC4.pspec
Normal file
@ -0,0 +1,9 @@
|
||||
<!-- Copyright 2023 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
Authors: Dan Genin and Tommy Johnson
|
||||
-->
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<processor_spec>
|
||||
<programcounter register="pc"/>
|
||||
</processor_spec>
|
66
Ghidra/Processors/ARC4/data/languages/ARC4.sinc
Normal file
66
Ghidra/Processors/ARC4/data/languages/ARC4.sinc
Normal file
@ -0,0 +1,66 @@
|
||||
# Copyright 2023 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
# Authors: Dan Genin and Tommy Johnson
|
||||
|
||||
# Main slaspec must define endianess and alignment
|
||||
|
||||
@ifndef WORDSIZE
|
||||
@define WORDSIZE "1"
|
||||
@endif
|
||||
|
||||
|
||||
define space ram type=ram_space size=$(SIZE) wordsize=$(WORDSIZE) default;
|
||||
define space register type=register_space size=2 wordsize=4;
|
||||
|
||||
# shimmflags, limm and shimnoflags act as dummy registers for instructions
|
||||
# with immediate value in destination register
|
||||
define register offset=0x1000 size=$(SIZE) [
|
||||
|
||||
r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14
|
||||
r15 r16 r17 r18 r19 r20 r21 r22 r23 r24 r25 r26 fp sp
|
||||
ilink1 ilink2 blink pc
|
||||
|
||||
ext0 ext1 ext2 ext3 ext4 ext5 ext6 ext7 ext8 ext9 ext10 ext11 ext12 ext13 ext14
|
||||
ext15 ext16 ext17 ext18 ext19 ext20 ext21 ext22 ext23 ext24 MLO MMID MHI lp_count
|
||||
shimmflags limm shimmnoflags
|
||||
|
||||
# r32-r59 reserved, lp_count is r60, MLO, MMID and MHI are only valid if the CPU has a 32x32 multiply extension.
|
||||
];
|
||||
|
||||
# STATUS REGISTER MAP: (LOW)
|
||||
# C - CARRY
|
||||
# Z - ZERO
|
||||
# N - NEGATIVE
|
||||
# V - OVERFLOW
|
||||
# tmp* are fake registers used to pass flags into FLAGS table
|
||||
define register offset=0x1200 size=1 [
|
||||
Z N C V tmpZ tmpN tmpC tmpV
|
||||
];
|
||||
|
||||
define register offset=0x1300 size=$(SIZE) [
|
||||
status semaphore lp_start lp_end identity debug
|
||||
aux6 aux7 aux8 aux9 aux10 aux11 aux12 aux13 aux14 aux15
|
||||
aux16 aux17 aux18 aux19 aux20 aux21 aux22 aux23 aux24 aux25
|
||||
aux26 aux27 aux28 aux29 aux30 aux31 aux32 aux33 aux34 aux35
|
||||
aux36 aux37 aux38 aux39 aux40 aux41 aux42 aux43 aux44 aux45
|
||||
aux46 aux47 aux48 aux49 aux50 aux51 aux52 aux53 aux54 aux55
|
||||
aux56 aux57 aux58 aux59 aux60 aux61 aux62 aux63
|
||||
];
|
||||
|
||||
# Fake register used to pass loop address into LP_COND table
|
||||
define register offset=0x1400 size=$(SIZE) [
|
||||
lp_addr
|
||||
];
|
||||
|
||||
define register offset=0x1500 size=8 [
|
||||
lp_status
|
||||
];
|
||||
|
||||
# NOTE: it appears that only one context register is allowed(?), so
|
||||
# we are making them longer to accommodate address variables
|
||||
# needed for computation in the action section of sr instruction
|
||||
# to support manual loop initialization.
|
||||
|
||||
define context lp_status
|
||||
lp_in_use = (0,0)
|
||||
# tmp1_1 = (32,63)
|
||||
;
|
791
Ghidra/Processors/ARC4/data/languages/ARC4Instructions.sinc
Normal file
791
Ghidra/Processors/ARC4/data/languages/ARC4Instructions.sinc
Normal file
@ -0,0 +1,791 @@
|
||||
# Copyright 2023 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
# Authors: Dan Genin and Tommy Johnson
|
||||
|
||||
define token instr(32)
|
||||
iI = (27, 31) # opcode
|
||||
iA = (21, 26) # destination reg
|
||||
iBL_L = (7,26) signed # destination address divided by 4
|
||||
iST_Di= (26, 26) # direct (cache bypass)
|
||||
iST_0 = (25, 25)
|
||||
iST_A = (24, 24) # address write-back enable
|
||||
iST_Z = (22, 23) # size field used by ST
|
||||
iA_alias = (21, 26) # necessary because iA cannot occur as both parameter and constraint at once
|
||||
iB = (15, 20) # op 1 address
|
||||
iB_alias = (15, 20)
|
||||
iSR_B = (15, 20)
|
||||
iC = (9, 14) # op 2 address
|
||||
iC_alias = (9, 14)
|
||||
iLD0_R = (13, 13) # reserved should be 0
|
||||
iLD1_R = (6, 8)
|
||||
iLD0_Di = (14, 14) # direct (cache bypass)
|
||||
iLD1_Di = (5, 5)
|
||||
iLD1_A = (12, 12) # address write-back enable (see ARC Ref. p. 99)
|
||||
iLD1_Z = (1, 2)
|
||||
iLD0_Z = (10, 11) # size field used by LD
|
||||
iLD0_X = (9, 9) # sign extend field
|
||||
iLD1_X = (0, 0)
|
||||
iF = (8, 8) # flags set field
|
||||
iR = (7, 7) # reserved, must be 0
|
||||
iN = (5, 6) # jump/call nullify instruction mode
|
||||
iQ = (0, 4) # condition flags
|
||||
iD = (0, 8) # short immediate data
|
||||
iLD0_A = (3,3) # address write-back enable for instruction without short immediate (see ARC Ref. p.100)
|
||||
iSR_D = (0, 5); # special register index for SR, note that this should
|
||||
# actually be (0, 8) but this would require making
|
||||
# the special register file 2^9 long.
|
||||
define token limm_token(32)
|
||||
limm32_field = (0,31);
|
||||
|
||||
attach names iQ [
|
||||
AL EQ NE PL MI CS CC VS VC GT GE LT LE HI LS PNZ ex0
|
||||
ex1 ex2 ex3 ex4 ex5 ex6 ex7 ex8 ex9 exA exB exC exD exE exF
|
||||
];
|
||||
|
||||
attach variables [ iA iB iC ] [
|
||||
r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14
|
||||
r15 r16 r17 r18 r19 r20 r21 r22 r23 r24 r25 r26 fp sp
|
||||
ilink1 ilink2 blink
|
||||
ext0 ext1 ext2 ext3 ext4 ext5 ext6 ext7 ext8 ext9 ext10 ext11 ext12 ext13 ext14
|
||||
ext15 ext16 ext17 ext18 ext19 ext20 ext21 ext22 ext23 ext24 MLO MMID MHI lp_count
|
||||
shimmflags limm shimmnoflags
|
||||
];
|
||||
|
||||
attach variables [ iSR_D iSR_B ] [
|
||||
status semaphore lp_start lp_end identity debug
|
||||
aux6 aux7 aux8 aux9 aux10 aux11 aux12 aux13 aux14 aux15
|
||||
aux16 aux17 aux18 aux19 aux20 aux21 aux22 aux23 aux24 aux25
|
||||
aux26 aux27 aux28 aux29 aux30 aux31
|
||||
aux32 aux33 aux34 aux35 aux36 aux37 aux38 aux39 aux40 aux41
|
||||
aux42 aux43 aux44 aux45 aux46 aux47 aux48 aux49 aux50 aux51
|
||||
aux52 aux53 aux54 aux55 aux56 aux57 aux58 aux59 aux60 aux61
|
||||
aux62 aux63
|
||||
];
|
||||
|
||||
# Short immediate arguments are sign extended to 32 bits. Ghidra sext()
|
||||
# requires byte aligned data but short immediate arguments are 9 bits long.
|
||||
# The work around is to sext(x)=(x<<23)s>>23. The combination of logical
|
||||
# left shift and signed arithmetic right shift is equivalent to sext on
|
||||
# the 9 bit short immediate value.
|
||||
#
|
||||
# The disassembly action section computes the 32 bit sign-extended operand
|
||||
# value. The variables in this section are arbitrary precision signed ones
|
||||
# complement. The expression in square brackets computes the correct signed
|
||||
# value by extracting the sign bit and effectively implementing
|
||||
# <sign bit> ? -iD : iD using arithmetic.
|
||||
# opD: val is iD [ val = ((iD&0x100)>>8)*(iD-512)+(1-((iD&0x100)>>8))*iD; ] { local tmp:4 = ((iD<<23)s>>23); export tmp; }
|
||||
opD: val is iD [ val = ((iD&0x100)>>8)*(iD-512)+(1-((iD&0x100)>>8))*iD; ] { local tmp:4 = ((iD&0x100)>>8)*(iD-512)+(1-((iD&0x100)>>8))*iD; export tmp; }
|
||||
|
||||
# p.61 of ARC Ref. regs 61-63 reserved for encoding immediate data
|
||||
|
||||
# 61 - Short immediate data indicator setting
|
||||
# flags
|
||||
# 62 - Long immediate data indicator
|
||||
# 63 - Short immediate data indicator not setting
|
||||
# flags
|
||||
|
||||
opA: iA is iA_alias<61 & iA { export iA; } # normal register operand
|
||||
opA: "0" is iA_alias=61 & iA { export iA; } # short immediate with flags set
|
||||
opA: "0" is iA_alias>61 & iA { export iA; } # short immediate without flags set or long immediate flags?
|
||||
# NOTEL: No long immediate for opA because it is the destination register. Short immediate for opA
|
||||
# is used for setting flags only.
|
||||
|
||||
opB: iB is iB_alias<61 & iB { export iB; } # normal register operand
|
||||
opB: opD is iB=61 & opD { local tmp:4 = opD; export tmp; } # short immediate with flags set
|
||||
opB: opD is iB=63 & opD { local tmp:4 = opD; export tmp; } # short immediate without flags set
|
||||
opB: limm32_field is iB_alias=62 & iB_alias; limm32_field { export *[const]:$(SIZE) limm32_field; } # long immediate
|
||||
|
||||
# SR instruction with implicit register specification, e.g.,
|
||||
# sr r1, [r2]
|
||||
# results in decompiler code with a RAM memory write, e.g.,
|
||||
# *(int **)((uVar1 & 0x3f) + 0x1300) = piParm2;
|
||||
# See discussion on SR for zero-overhead loop instruction below.
|
||||
opSR_B: iSR_B is iB_alias<61 & iSR_B { export iSR_B; } # normal register operand
|
||||
opSR_B: iSR_D is iSR_B=61 & iSR_D { export iSR_D; } # short immediate with flags set
|
||||
opSR_B: iSR_D is iSR_B=63 & iSR_D { export iSR_D; } # short immediate without flags set
|
||||
opSR_B: limm32_field is iB_alias=62 & iB_alias; limm32_field { export *[const]:$(SIZE) limm32_field; } # long immediate
|
||||
|
||||
opC: iC is iC_alias<61 & iC { export iC; } # normal register operand
|
||||
opC: opD is iC=61 & opD { local tmp:4 = opD; export tmp; } # short immediate with flags set
|
||||
opC: opD is iC=63 & opD { local tmp:4 = opD; export tmp; } # short immediate without flags set
|
||||
opC: limm32_field is iC=62; limm32_field { export *[const]:$(SIZE) limm32_field; } # long immediate
|
||||
|
||||
cc: "" is iQ=0 { export 1:1; } #not displaying anything for always-execute
|
||||
cc: ".eq" is iQ=1 { export Z; }
|
||||
cc: ".ne" is iQ=2 { tmp:1 = !Z; export tmp; }
|
||||
cc: ".pl" is iQ=3 { tmp:1 = !N; export tmp; }
|
||||
cc: ".mi" is iQ=4 { export N; }
|
||||
cc: ".cs" is iQ=5 { export C; }
|
||||
cc: ".cc" is iQ=6 { tmp:1 = !C; export tmp; }
|
||||
cc: ".vs" is iQ=7 { export V; }
|
||||
cc: ".vc" is iQ=8 { tmp:1 = !V; export tmp; }
|
||||
cc: ".gt" is iQ=9 { tmp:1 = (!Z) && (N==V); export tmp; }
|
||||
cc: ".ge" is iQ=10 { tmp:1 = (N==V); export tmp; }
|
||||
cc: ".lt" is iQ=11 { tmp:1 = (N!=V); export tmp; }
|
||||
cc: ".le" is iQ=12 { tmp:1 = Z || (N!=V); export tmp; }
|
||||
cc: ".hi" is iQ=13 { tmp:1 = C && (!Z); export tmp; }
|
||||
cc: ".ls" is iQ=14 { tmp:1 = (!C) || Z; export tmp; }
|
||||
cc: ".pnz" is iQ=15 { tmp:1 = (!Z) && (!N); export tmp; }
|
||||
|
||||
COND: cc is cc & (iQ=0 & iC!=61 & iC!=63 & iB!=61 & iB!=63) { }
|
||||
COND: cc is cc & (iC!=61 & iC!=63 & iB!=61 & iB!=63) { if (!cc) goto inst_next; }
|
||||
# Always execute
|
||||
COND: "" is ((iC > 60 & iC != 62) | (iB > 60 & iB != 62)) { } #(iC=61 | iC=63 | iB=61 | iB=63) { }
|
||||
|
||||
B_COND: cc is cc & (iQ!=0) { if (!cc) goto inst_next; }
|
||||
# This avoids inserting a conditional branch in the case where
|
||||
# the jump is in fact unconditional.
|
||||
B_COND: cc is cc & (iQ=0) { }
|
||||
|
||||
# lp instruction does not use iA, iB, iC or iD fields but only iBL_L and iQ.
|
||||
# So, LP_COND does not need to check instruction mode (long vs short immediate, register)
|
||||
# the way COND does.
|
||||
LP_COND: ".al" is (iQ=0) { }
|
||||
LP_COND: cc is cc & (iQ!=0) { if (cc) goto <skip>; goto [lp_addr]; <skip> }
|
||||
|
||||
|
||||
# TODO: Try jumps with short immediate data which is not documented in the specification.
|
||||
# Doesn't seem to be possible to force assembler to produce a jump with a short immediate
|
||||
# JADDR: byte_addr is iB_alias<61 & iB { export iB; } # normal register operand
|
||||
# JADDR: byte_addr is iB=61 & iD { export *[const]:$(SIZE) iD; } # short immediate with flags set
|
||||
# JADDR: byte_addr is iB=63 & iD { export *[const]:$(SIZE) iD; } # short immediate without flags set
|
||||
JADDR: byte_addr is iB_alias=62 & iB_alias; limm32_field [ byte_addr = (limm32_field & 0xFFFFFF) <<2; ] { export *[ram]:4 byte_addr; } # long immediate
|
||||
|
||||
|
||||
ADDR: reloc is iBL_L [ reloc = inst_next + (4*iBL_L); ] { export *[ram]:4 reloc; }
|
||||
LP_ADDR: reloc is iBL_L [ reloc = inst_next + (4*iBL_L); ] { export *[const]:$(SIZE) reloc; }
|
||||
# Computes address of one instruction before the last instruction named the loop instruction
|
||||
# to restrict loop branching p-code to only the final instruction in the loop.
|
||||
# This avoids Ghidra complaining about unreachable blocks if end-of-loop testing
|
||||
# p-code is inserted into every instruction, which is how hardware does it.
|
||||
PREV_ADDR: reloc is iBL_L [ reloc = inst_next + (4*iBL_L) - 4; ] { export *[const]:$(SIZE) reloc; }
|
||||
|
||||
PREV_opC: res is iC_alias<61 & iC [ res = (iC<<2) - 4; ] { export *[const]:$SIZE res; } # normal register operand
|
||||
PREV_opC: res is iC=61 & iD [ res = (iD<<2) - 4; ] { export *[const]:$(SIZE) res; } # short immediate with flags set
|
||||
PREV_opC: res is iC=63 & iD [ res = (iD<<2) - 4; ] { export *[const]:$(SIZE) res; } # short immediate without flags set
|
||||
PREV_opC: res is iC=62; limm32_field [ res = (limm32_field<<2) - 4; ]{ export *[const]:$(SIZE) res; } # long immediate
|
||||
|
||||
dd: ".nd" is iN=0 { } # Only execute next instruction when not jumping (Default)
|
||||
dd: ".d" is iN=1 { delayslot(1); } # Always execute next instruction
|
||||
dd: ".jd" is (iN=2)&cc { if (!cc) goto <skip>; delayslot(1); <skip> } # Only execute next instruction when jumping (see p.88)
|
||||
|
||||
# NOTE: This is used only for jl with long immediate address, which occupies
|
||||
# the delay slot. According to the ARC4 spec .jd nullify mode must be
|
||||
# used (p. 97).
|
||||
jl_dd: ".jd" is iN=2 { }
|
||||
|
||||
# p.36 ARC4 CPU manual
|
||||
# Adds end-of-loop p-code test to the last instruction in the loop,
|
||||
# which is the only instruction for which lp_in_use is 1.
|
||||
LOOP: is (lp_in_use=0) {}
|
||||
LOOP: is (lp_in_use=1)
|
||||
{
|
||||
# if next instruction is not the end of the loop do nothing
|
||||
if (inst_next!=lp_end) goto <skip>;
|
||||
# if next instruction is the end of the loop
|
||||
# decrement lp_count
|
||||
lp_count = lp_count - 1;
|
||||
# if lp_count is 0 do nothing
|
||||
if (lp_count==0) goto <skip>;
|
||||
# otherwise return to the start of the loop
|
||||
goto [lp_start];
|
||||
<skip>
|
||||
}
|
||||
|
||||
macro resultflags(result) {
|
||||
tmpN = result s< 0;
|
||||
tmpZ = result == 0;
|
||||
}
|
||||
|
||||
macro addflags(op1,op2) {
|
||||
tmpC = carry(op1,op2);
|
||||
tmpV = scarry(op1,op2);
|
||||
}
|
||||
|
||||
# NOTE: unlike x86, carry flag is SET if there is NO borrow
|
||||
macro subflags(op1,op2) {
|
||||
tmpC = op2 <= op1;
|
||||
tmpV = sborrow(op1,op2);
|
||||
}
|
||||
|
||||
FLAGS: ".f" is iF=1 & (iC!=61 & iC!=63 & iB!=61 & iB!=63) { C = tmpC; Z = tmpZ; N = tmpN; V = tmpV; }
|
||||
FLAGS: "" is iF=0 & (iC!=61 & iC!=63 & iB!=61 & iB!=63) { }
|
||||
FLAGS: ".f" is (iC<63 & iB<63) { C = tmpC; Z = tmpZ; N = tmpN; V = tmpV; }
|
||||
FLAGS: "" is (iC=63 | iB=63) { }
|
||||
|
||||
FLAGSNZ: ".f" is iF=1 & (iC!=opC61 & iC!=63 & iB!=61 & iB!=63) { N = tmpN; Z = tmpZ; }
|
||||
FLAGSNZ: "" is iF=0 & (iC!=61 & iC!=63 & iB!=61 & iB!=63) { }
|
||||
FLAGSNZ: ".f" is (iC<63 & iB<63) { N = tmpN; Z = tmpZ; }
|
||||
FLAGSNZ: "" is (iC=63 | iB=63) { }
|
||||
|
||||
|
||||
ADDRESS_WRITEBACK_LD0: ".a" is iLD0_A=1 ... & opB & opC { opB = opB + opC; export opB; }
|
||||
ADDRESS_WRITEBACK_LD0: "" is iLD0_A=0 ... & opB & opC { local tmp = opB + opC; export tmp; }
|
||||
ADDRESS_WRITEBACK_LD1: ".a" is iLD1_A=1 ... & opB & opD ... { opB = opB + opD; export opB; }
|
||||
ADDRESS_WRITEBACK_LD1: "" is iLD1_A=0 ... & opB & opD ... { local tmp = opB + opD; export tmp; }
|
||||
ADDRESS_WRITEBACK_ST0: ".a" is iST_A=1 ... & opB & opD ... { opB = opB + opD; export opB; }
|
||||
ADDRESS_WRITEBACK_ST0: "" is iST_A=0 ... & opB & opD ... { local tmp = opB + opD; export tmp; }
|
||||
|
||||
# p. 93 of ARC Ref
|
||||
# TODO: implement cache bypass and sign extend
|
||||
# NOTE: ld instruction family does not set status flags see p.100
|
||||
# LD instructions below use
|
||||
|
||||
:ld^ADDRESS_WRITEBACK_LD0 opA, "["^opB, opC^"]" is LOOP & ADDRESS_WRITEBACK_LD0 & (iI=0x0 & iLD1_Z=0x0 & iLD1_R=0x0) ... & opA ... & opB & opC ...
|
||||
{
|
||||
opA = *:4 ADDRESS_WRITEBACK_LD0;
|
||||
}
|
||||
|
||||
:ldb^ADDRESS_WRITEBACK_LD0 opA, "["^opB, opC^"]" is LOOP & ADDRESS_WRITEBACK_LD0 & (iI=0x0 & iLD1_Z=0x1 & iLD1_R=0x0) ... & opA ... & opB & opC ...
|
||||
{
|
||||
local tmp = *:1 ADDRESS_WRITEBACK_LD0;
|
||||
opA = zext(tmp);
|
||||
}
|
||||
|
||||
:ldw^ADDRESS_WRITEBACK_LD0 opA, "["^opB, opC^"]" is LOOP & ADDRESS_WRITEBACK_LD0 & (iI=0x0 & iLD1_Z=0x2 & iLD1_R=0x0) ... & opA ... & opB & opC ...
|
||||
{
|
||||
local tmp = *:2 ADDRESS_WRITEBACK_LD0;
|
||||
opA = zext(tmp);
|
||||
}
|
||||
# LD instructions below use short immediate addressing, e.g., ld r1,[r2,4]
|
||||
:ld^ADDRESS_WRITEBACK_LD1 opA, "["^opB, opD^"]" is LOOP & ADDRESS_WRITEBACK_LD1 & (iI=0x1 & iLD0_Z=0x0 & iLD0_R=0) ... & opA ... & opB & opD ...
|
||||
{
|
||||
opA = *:4 ADDRESS_WRITEBACK_LD1;
|
||||
}
|
||||
|
||||
:ldb^ADDRESS_WRITEBACK_LD1 opA, "["^opB, opD^"]" is LOOP & ADDRESS_WRITEBACK_LD1 & (iI=0x1 & iLD0_Z=0x1 & iLD0_R=0) ... & opA ... & opB & opD ...
|
||||
{
|
||||
local tmp = *:1 ADDRESS_WRITEBACK_LD1;
|
||||
opA = zext(tmp);
|
||||
}
|
||||
|
||||
:ldw^ADDRESS_WRITEBACK_LD1 opA, "["^opB, opD^"]" is LOOP & ADDRESS_WRITEBACK_LD1 & (iI=0x1 & iLD0_Z=0x2 & iLD0_R=0) ... & opA ... & opB & opD ...
|
||||
{
|
||||
local tmp = *:2 ADDRESS_WRITEBACK_LD1;
|
||||
opA = zext(tmp);
|
||||
}
|
||||
|
||||
:lr opA, "["^opB^"]" is LOOP & (iI=0x1 & iC=0x10) ... & opA ... & opB
|
||||
{
|
||||
local addr = &:2 status + opB:2;
|
||||
reg_val = *[register] addr;
|
||||
opA = reg_val;
|
||||
}
|
||||
|
||||
:lr_but_reserved_bits_not_zero opA, "["^opB^"]" is LOOP & (iI=0x1 & iLD0_R=0x1 & iC!=0x10) ... & opA ... & opB & iD ...
|
||||
{
|
||||
local addr = &:2 status + opB:2;
|
||||
reg_val = *[register] addr;
|
||||
opA = reg_val;
|
||||
}
|
||||
|
||||
|
||||
# lp_end = 3
|
||||
# NOTE: Zero-overhead loop setup with explicit stores to auxiliary registers cannot
|
||||
# be made to work with existing implementation. The reason is that it requires
|
||||
# constants propagation for the disassembler to be able to insert p-code
|
||||
# jump at the correct instruction. The address of the loop end instruction
|
||||
# must be computed from the corresponding label (using left shift?), which
|
||||
# means it cannot be explicitly computed at compile time by assembler and
|
||||
# therefore cannot be an immediate. So loop_end setup requires a register
|
||||
# store, e.g., sr r1, [lp_end], where r1 holds the computed address of the
|
||||
# end of the loop.
|
||||
# The lp instruction circumvents this issue by using pc-relative addressing,
|
||||
# so that the loop end instruction address can be computed by the disassembler.
|
||||
# lp instruction therefore behaves like a branch instruction.
|
||||
#
|
||||
# Unrelated, the gcc ARC4 assembler appears to OR short immediates in auxiliary
|
||||
# register store instructions, making it impossible to use code like
|
||||
# sr 0x8e, [lp_end], which assembles into sr 0x8f, [0x8f]. It should have been
|
||||
# assembled into an instruction using a short immediate and a long immediate,
|
||||
# instead the two immediates are ORed into the short immediate field. Brilliant!
|
||||
#
|
||||
# NOTE: opC is not allowed in square brackets so we need to make
|
||||
# equivalents of ADDR and PREV_ADDR to get the right values in to
|
||||
# square brackets.
|
||||
:sr opC, "["^opB^"]" is PREV_opC & LOOP & (iI=0x2 & iA=0x10 & (iB=61 | iB=63) & iD=0x3) ... & opC ... & opB ... & iD ...
|
||||
[
|
||||
# Set lp_in_use context variable for the last
|
||||
# instrution at the end of the loop so that
|
||||
# the end-of-loop check is performed only
|
||||
# in that instruction.
|
||||
# NOTE: if lp_end is overwritten while the
|
||||
# loop is running there will be sadness:'(
|
||||
# lp_in_use=1;
|
||||
# globalset(inst_next, lp_in_use);
|
||||
# lp_in_use=0;
|
||||
# This still results in unreachable branches because register value
|
||||
# is not known at decompile time and lp_in_use ends up being set
|
||||
# everywhere (see discussion on SR for zero-overhead loop).
|
||||
lp_in_use=1;
|
||||
globalset(PREV_opC, lp_in_use);
|
||||
lp_in_use=0;
|
||||
globalset(opC, lp_in_use);
|
||||
]
|
||||
{
|
||||
lp_end = opC<<2;
|
||||
}
|
||||
|
||||
:sr opC, "["^opB^"]" is LOOP & (iI=0x2 & iA=0x10 & iD!=0x3) ... & opC ... & opB ... & iD ...
|
||||
{
|
||||
*[register] (&:2 status + opB:2) = opC;
|
||||
}
|
||||
|
||||
:st^ADDRESS_WRITEBACK_ST0 opC, "["^opB, opD^"]" is LOOP & ADDRESS_WRITEBACK_ST0 & (iI=0x2 & iST_Z=0x0 & iST_0=0) ... & opB ... & opC & opD ...
|
||||
{
|
||||
*:4 ADDRESS_WRITEBACK_ST0 = opC:4;
|
||||
}
|
||||
|
||||
:stb^ADDRESS_WRITEBACK_ST0 opC, "["^opB, opD^"]" is LOOP & ADDRESS_WRITEBACK_ST0 & (iI=0x2 & iST_Z=0x1 & iST_0=0)... & opB ... & opC & opD ...
|
||||
{
|
||||
*:1 ADDRESS_WRITEBACK_ST0 = opC:1;
|
||||
}
|
||||
|
||||
:stw^ADDRESS_WRITEBACK_ST0 opC, "["^opB, opD^"]" is LOOP & ADDRESS_WRITEBACK_ST0 & (iI=0x2 & iST_Z=0x2 & iST_0=0) ... & opB ... & opC & opD ...
|
||||
{
|
||||
*:2 ADDRESS_WRITEBACK_ST0 = opC:2;
|
||||
}
|
||||
|
||||
:ext_unknown_instruction_3^COND^FLAGSNZ opA, opB is LOOP & COND ... & FLAGSNZ ... & (iI=0x3&iC=0x3f) ... & opA ... & opB ...
|
||||
{
|
||||
build COND;
|
||||
}
|
||||
|
||||
# TODO: implement p-code
|
||||
:norm^COND^FLAGSNZ opA, opB is LOOP & COND ... & FLAGSNZ ... & (iI=0x3&iC=10) ... & opA ... & opB ...
|
||||
{
|
||||
build COND;
|
||||
}
|
||||
|
||||
# TODO: implement p-code
|
||||
:swap^COND^FLAGSNZ opA, opB is LOOP & COND ... & FLAGSNZ ... & (iI=0x3&iC=9) ... & opA ... & opB ...
|
||||
{
|
||||
build COND;
|
||||
}
|
||||
|
||||
:extw^COND^FLAGSNZ opA, opB is LOOP & COND ... & FLAGSNZ ... & (iI=0x3&iC=8) ... & opA ... & opB ...
|
||||
{
|
||||
build COND;
|
||||
opA = zext(opB:2);
|
||||
resultflags(opA);
|
||||
build FLAGSNZ;
|
||||
}
|
||||
|
||||
:extb^COND^FLAGSNZ opA, opB is LOOP & COND ... & FLAGSNZ ... & (iI=0x3&iC=7) ... & opA ... & opB ...
|
||||
{
|
||||
build COND;
|
||||
opA = zext(opB:1);
|
||||
resultflags(opA);
|
||||
build FLAGSNZ;
|
||||
}
|
||||
|
||||
:sexw^COND^FLAGSNZ opA, opB is LOOP & COND ... & FLAGSNZ ... & (iI=0x3&iC=6) ... & opA ... & opB ...
|
||||
{
|
||||
build COND;
|
||||
opA = sext(opB:2);
|
||||
resultflags(opA);
|
||||
build FLAGSNZ;
|
||||
}
|
||||
|
||||
:sexb^COND^FLAGSNZ opA, opB is LOOP & COND ... & FLAGSNZ ... & (iI=0x3&iC=5) ... & opA ... & opB ...
|
||||
{
|
||||
build COND;
|
||||
opA = sext(opB:1);
|
||||
resultflags(opA);
|
||||
build FLAGSNZ;
|
||||
}
|
||||
|
||||
:rrc^COND^FLAGS opA, opB is LOOP & COND ... & FLAGS ... & (iI=0x3&iC=4) ... & opA ... & opB ...
|
||||
{
|
||||
build COND;
|
||||
tmpC = opB[0,1];
|
||||
tmpV = V;
|
||||
opA = (opB>>1)|(zext(C)<<31);
|
||||
resultflags(opA);
|
||||
build FLAGS;
|
||||
}
|
||||
|
||||
:ror^COND^FLAGSNZ opA, opB is LOOP & COND ... & FLAGSNZ ... & (iI=0x3&iC=3) ... & opA ... & opB ...
|
||||
{
|
||||
build COND;
|
||||
tmpC = opB[0,1];
|
||||
tmpV = V;
|
||||
opA = (opB>>1)|(zext(tmpC)<<31);
|
||||
resultflags(opA);
|
||||
build FLAGSNZ;
|
||||
}
|
||||
|
||||
:lsr^COND^FLAGSNZ opA, opB is LOOP & COND ... & FLAGSNZ ... & (iI=0x3&iC=2) ... & opA ... & opB ...
|
||||
{
|
||||
build COND;
|
||||
tmpC = opB[0,1];
|
||||
tmpV = V;
|
||||
opA = opB>>1;
|
||||
resultflags(opA);
|
||||
build FLAGSNZ;
|
||||
}
|
||||
|
||||
:asr^COND^FLAGS opA, opB is LOOP & COND ... & FLAGS ... & (iI=0x3&iC=1) ... & opA ... & opB ...
|
||||
{
|
||||
build COND;
|
||||
tmpC = opB[0,1];
|
||||
tmpV = V;
|
||||
opA = (opB>>1)|(opB&0x80000000);
|
||||
resultflags(opA);
|
||||
build FLAGS;
|
||||
}
|
||||
|
||||
# NOTE: Effect of setting interrupt flag bits E1 (1), E2 (2) and the halt bit H (0) is not implemented.
|
||||
# NOTE: Documentation specifies that the flag bit (8) must be cleared or the flag instruction will
|
||||
# not set the flags.
|
||||
:flag^COND opB is LOOP & COND ... & (iI=0x3&iA=0x3D&iC=0) ... & opA ... & opB ...
|
||||
{
|
||||
build COND;
|
||||
Z = opB[6,1];
|
||||
N = opB[5,1];
|
||||
C = opB[4,1];
|
||||
V = opB[3,1];
|
||||
# E2 = opB[2,1];
|
||||
# E1 = opB[1,1];
|
||||
# H = opB[0,1];
|
||||
}
|
||||
|
||||
:flag_but_A_field_is_wrong^COND opB is LOOP & COND ... & (iI=0x3&iA!=0x3D&iC=0) ... & opA ... & opB ...
|
||||
{
|
||||
build COND;
|
||||
Z = opB[6,1];
|
||||
N = opB[5,1];
|
||||
C = opB[4,1];
|
||||
V = opB[3,1];
|
||||
# E2 = opB[2,1];
|
||||
# E1 = opB[1,1];
|
||||
# H = opB[0,1];
|
||||
}
|
||||
|
||||
:b^B_COND^dd ADDR is LOOP & (iI=0x4) & B_COND & dd & ADDR
|
||||
{
|
||||
build B_COND;
|
||||
build ADDR;
|
||||
goto ADDR;
|
||||
}
|
||||
|
||||
:bl^B_COND^dd ADDR is LOOP & (iI=0x5) & B_COND & dd & ADDR
|
||||
{
|
||||
build B_COND;
|
||||
build ADDR;
|
||||
blink = inst_next;
|
||||
call ADDR;
|
||||
}
|
||||
|
||||
:lp^LP_COND^dd LP_ADDR PREV_ADDR is PREV_ADDR & LOOP & (iI=0x6) & LP_COND & dd & LP_ADDR
|
||||
[
|
||||
# Set lp_in_use context variable for the last
|
||||
# instrution at the end of the loop so that
|
||||
# the end-of-loop check is performed only
|
||||
# in that instruction.
|
||||
# NOTE: if lp_end is overwritten while the
|
||||
# loop is running there will be sadness:'(
|
||||
# NOTE: Order of disassembly matters. If the last
|
||||
# instruction in the loop is disassembled before
|
||||
# lp instruction that sets up the loop, the
|
||||
# lp_in_use context register will not be set
|
||||
# when lp is finally disassembled, and the loop
|
||||
# will magically disappear (poof).
|
||||
lp_in_use=1;
|
||||
globalset(PREV_ADDR, lp_in_use);
|
||||
lp_in_use=0;
|
||||
globalset(LP_ADDR, lp_in_use);
|
||||
]
|
||||
{
|
||||
build LP_ADDR;
|
||||
lp_addr = LP_ADDR;
|
||||
build LP_COND;
|
||||
lp_start = inst_next;
|
||||
lp_end = LP_ADDR;
|
||||
}
|
||||
|
||||
# Special case for j blink
|
||||
:j^COND^dd^FLAGS opB is LOOP & (COND & dd & FLAGS & iI=0x7 & iA=0 & iB=0x1F & iC=0) ... & opB
|
||||
{
|
||||
build COND;
|
||||
tmpZ = opB[31,1];
|
||||
tmpN = opB[30,1];
|
||||
tmpC = opB[29,1];
|
||||
tmpV = opB[28,1];
|
||||
build FLAGS;
|
||||
return [blink];
|
||||
}
|
||||
|
||||
:j^COND^dd^FLAGS JADDR is LOOP & COND ... & FLAGS ... & dd ... & (iI=0x7 & iA=0 & iB=62 & iC=0) ... & opB & JADDR
|
||||
{
|
||||
build COND;
|
||||
tmpZ = opB[31,1];
|
||||
tmpN = opB[30,1];
|
||||
tmpC = opB[29,1];
|
||||
tmpV = opB[28,1];
|
||||
build FLAGS;
|
||||
goto JADDR;
|
||||
}
|
||||
|
||||
:j^COND^dd^FLAGS opB is LOOP & COND ... & FLAGS ... & dd ... & (iI=0x7 & iA=0 & iB<61 & iB!=0x1F & iC=0) ... & opB
|
||||
{
|
||||
build COND;
|
||||
local addr = (opB&0x0FFFFFF)<<2;
|
||||
tmpZ = opB[31,1];
|
||||
tmpN = opB[30,1];
|
||||
tmpC = opB[29,1];
|
||||
tmpV = opB[28,1];
|
||||
build FLAGS;
|
||||
goto [addr];
|
||||
}
|
||||
|
||||
# iB==62 => long immediate
|
||||
:jl^COND^jl_dd^FLAGS JADDR is LOOP & COND ... & FLAGS ... & jl_dd ... & (iI=0x7 & iA=0 & iB=62 & iC=1) ... & opB & JADDR
|
||||
{
|
||||
build COND;
|
||||
tmpZ = opB[31,1];
|
||||
tmpN = opB[30,1];
|
||||
tmpC = opB[29,1];
|
||||
tmpV = opB[28,1];
|
||||
build FLAGS;
|
||||
blink = inst_next;
|
||||
call JADDR;
|
||||
}
|
||||
|
||||
:jl^COND^dd^FLAGS opB is LOOP & COND ... & FLAGS ... & dd ... & (iI=0x7 & iA=0 & iB<61 & iC=1) ... & opB
|
||||
{
|
||||
build COND;
|
||||
local addr = (opB&0x0FFFFFF)<<2;
|
||||
tmpZ = opB[31,1];
|
||||
tmpN = opB[30,1];
|
||||
tmpC = opB[29,1];
|
||||
tmpV = opB[28,1];
|
||||
build FLAGS;
|
||||
blink = inst_next;
|
||||
call [addr];
|
||||
}
|
||||
|
||||
:add^COND^FLAGS opA, opB, opC is LOOP & COND ... & FLAGS ... & iI=0x8 ... & opA ... & opB & opC
|
||||
{
|
||||
build COND;
|
||||
opA = opB + opC;
|
||||
local result = opA;
|
||||
resultflags(result);
|
||||
addflags(opB, opC);
|
||||
# logicflags();
|
||||
build FLAGS;
|
||||
build LOOP;
|
||||
}
|
||||
|
||||
:adc^COND^FLAGS opA, opB, opC is LOOP & COND ... & FLAGS ... & iI=0x9 ... & opA ... & opB & opC
|
||||
{
|
||||
build COND;
|
||||
opA = opB + opC + zext(C);
|
||||
local result = opA;
|
||||
resultflags(result);
|
||||
addflags(opB, opC);
|
||||
build FLAGS;
|
||||
}
|
||||
|
||||
:sub^COND^FLAGS opA, opB, opC is LOOP & COND ... & FLAGS ... & iI=0xA ... & opA ... & opB & opC
|
||||
{
|
||||
build COND;
|
||||
opA = opB - opC;
|
||||
local result = opA;
|
||||
resultflags(result);
|
||||
subflags(opB, opC);
|
||||
build FLAGS;
|
||||
}
|
||||
|
||||
:sbc^COND^FLAGS opA, opB, opC is LOOP & COND ... & FLAGS ... & iI=0xB ... & opA ... & opB & opC
|
||||
{
|
||||
build COND;
|
||||
opA = opB - opC - zext(C);
|
||||
local result = opA;
|
||||
resultflags(result);
|
||||
subflags(opB, opC);
|
||||
build FLAGS;
|
||||
}
|
||||
|
||||
:and^COND^FLAGSNZ opA, opB, opC is LOOP & COND ... & FLAGSNZ ... & iI=0xC ... & opA ... & opB & opC
|
||||
{
|
||||
build COND;
|
||||
opA = opB & opC;
|
||||
local result = opA;
|
||||
resultflags(result);
|
||||
build FLAGSNZ;
|
||||
}
|
||||
|
||||
# with mov : iI = 0xC
|
||||
# and reg, shimm, shimm
|
||||
:mov^COND^FLAGSNZ opA, opB is LOOP & COND ... & FLAGSNZ ... & (iI=0xC & (iB=61 | iB=63) & (iC=61 | iC=63)) ... & opA ... & opB & opC
|
||||
{
|
||||
build COND;
|
||||
opA = opB; # & opC;
|
||||
local result = opA;
|
||||
resultflags(result);
|
||||
build FLAGSNZ;
|
||||
}
|
||||
|
||||
# and reg, limm, limm
|
||||
:mov^COND^FLAGSNZ opA, opB is LOOP & COND ... & FLAGSNZ ... & (iI=0xC & iB=62 & iC=62) ... & opA ... & opB & opC
|
||||
{
|
||||
build COND;
|
||||
opA = opB; # & opC;
|
||||
local result = opA;
|
||||
resultflags(result);
|
||||
build FLAGSNZ;
|
||||
}
|
||||
|
||||
# and dst_reg, src_reg, src_reg
|
||||
:mov^COND^FLAGSNZ opA, opB is LOOP & COND ... & FLAGSNZ ... & (iI=0xC & iB=iC & iB<61 & iC<61) ... & opA ... & opB& opC
|
||||
{
|
||||
build COND;
|
||||
opA = opB; # & opC;
|
||||
local result = opA;
|
||||
resultflags(result);
|
||||
build FLAGSNZ;
|
||||
}
|
||||
|
||||
# and shimm, op1, op1
|
||||
:tst^COND^FLAGSNZ opB is LOOP & COND ... & FLAGSNZ ... & (iI=0xC & iA=63 & iB=iC & iB<61 & iC<61) ... & opA ... & opB & opC
|
||||
{
|
||||
build COND;
|
||||
opA = opB & opC;
|
||||
local result = opA;
|
||||
resultflags(result);
|
||||
build FLAGSNZ;
|
||||
}
|
||||
|
||||
:or^COND^FLAGSNZ opA, opB, opC is LOOP & COND ... & FLAGSNZ ... & iI=0xD ... & opA ... & opB & opC
|
||||
{
|
||||
build COND;
|
||||
opA = opB | opC;
|
||||
local result = opA;
|
||||
resultflags(result);
|
||||
build FLAGSNZ;
|
||||
}
|
||||
|
||||
:bic^COND^FLAGSNZ opA, opB, opC is LOOP & COND ... & FLAGSNZ ... & iI=0xE ... & opA ... & opB & opC
|
||||
{
|
||||
build COND;
|
||||
opA = opB & (~opC);
|
||||
local result = opA;
|
||||
resultflags(result);
|
||||
build FLAGSNZ;
|
||||
}
|
||||
|
||||
:xor^COND^FLAGSNZ opA, opB, opC is LOOP & COND ... & FLAGSNZ ... & iI=0xF ... & opA ... & opB & opC
|
||||
{
|
||||
build COND;
|
||||
opA = opB ^ opC;
|
||||
local result = opA;
|
||||
resultflags(result);
|
||||
build FLAGSNZ;
|
||||
}
|
||||
|
||||
# # ROR p.119
|
||||
# :ror^COND^FLAGS opA, opB is LOOP & COND ... & FLAGS ... & (iI=0x3&iC=3) ... & opA ... & opB
|
||||
# {
|
||||
# build COND;
|
||||
# local tmp = (opB & 0x1);
|
||||
# tmpC = tmp:1;
|
||||
# opA = (opB >> 1) | (tmp << 31);
|
||||
# local result = opA;
|
||||
# resultflags(result);
|
||||
# tmpV = V;
|
||||
# build FLAGS;
|
||||
# }
|
||||
|
||||
# ROR multiple p.120
|
||||
:rorm^COND^FLAGS opA, opB, opC is LOOP & COND ... & FLAGS ... & iI=0x13 ... & opA ... & opB & opC
|
||||
{
|
||||
build COND;
|
||||
opA = (opB >> opC) | (opB << (32-opC));
|
||||
local result = opA;
|
||||
resultflags(result);
|
||||
tmpV = V;
|
||||
tmpC = C;
|
||||
build FLAGS;
|
||||
}
|
||||
|
||||
# ASL multiple p.84
|
||||
:asl^COND^FLAGSNZ opA, opB, opC is LOOP & COND ... & FLAGSNZ ... & iI=0x10 ... & opA ... & opB & opC
|
||||
{
|
||||
build COND;
|
||||
opA = opB << opC;
|
||||
# TODO: Result is redundant. Pass opA directly to resultflags throughout.
|
||||
local result = opA;
|
||||
resultflags(result);
|
||||
build FLAGSNZ;
|
||||
}
|
||||
|
||||
|
||||
# ASL p.8 3
|
||||
# NOTE: The specification has an _error_ where it claims that iI=0xC if there is no short immediate argument.
|
||||
# This conflicts with the definition of ADD, which has the same op code and is also contradicted
|
||||
# by the assembler.
|
||||
:asl^COND^FLAGS opA, opB is LOOP & COND ... & FLAGS ... & iI=0x8 ... & iB=iC ... & opA ... & opB
|
||||
{
|
||||
build COND;
|
||||
local tmp = (opB & 0x80000000) >> 31;
|
||||
tmpC = tmp:1;
|
||||
opA = opB << 1;
|
||||
local result = opA;
|
||||
resultflags(result);
|
||||
tmpV = (tmpN != N);
|
||||
build FLAGS;
|
||||
}
|
||||
|
||||
:lsr^COND^FLAGS opA, opB, opC is LOOP & COND ... & FLAGS ... & iI=0x11 ... & opA ... & opB & opC
|
||||
{
|
||||
build COND;
|
||||
opA = opB >> opC;
|
||||
resultflags(opA);
|
||||
build FLAGS;
|
||||
}
|
||||
|
||||
:asr^COND^FLAGS opA, opB, opC is LOOP & COND ... & FLAGS ... & iI=0x12 ... & opA ... & opB & opC
|
||||
{
|
||||
build COND;
|
||||
local tmp = ((opB & 0x80000000) >> 31);
|
||||
if (tmp[0,1]) goto <skip>;
|
||||
tmp = 0xFFFFFFFF << (32 - opC);
|
||||
<skip>
|
||||
opA = (opB >> opC) | tmp;
|
||||
resultflags(opA);
|
||||
build FLAGS;
|
||||
}
|
||||
|
||||
:nop^COND^FLAGS is LOOP & COND & FLAGS & iI=0xF & iA=63 & iB=63 & iC=63 & iD=0x1FF
|
||||
{
|
||||
}
|
||||
|
||||
# TODO: implement signed mul64
|
||||
# Idea: convert to unsigned, use unsigned multiplication on 31 bit unsigned operands,
|
||||
# compute the correct sign for the product by xor-ing the sign bits of the operands,
|
||||
# if it's negative convert the result to two's complement.
|
||||
:mul64^COND opB, opC is LOOP & COND ... & iI=0x14 ... & iA=0x3F ... & opB & opC
|
||||
{
|
||||
build COND;
|
||||
local tmp_b:12 = 0;
|
||||
tmp_b[0,31] = opB;
|
||||
local tmp_c:12 = 0;
|
||||
tmp_c[0,31] = opC;
|
||||
local res:12 = tmp_b * tmp_c;
|
||||
MLO = res[0,31];
|
||||
MMID = res[32,31];
|
||||
MHI = res[64,31];
|
||||
}
|
||||
|
||||
:mulu64^COND opB, opC is LOOP & COND ... & iI=0x15 ... & iA=0x3F ... & opB & opC
|
||||
{
|
||||
build COND;
|
||||
local tmp_b:12 = 0;
|
||||
tmp_b[0,31] = opB;
|
||||
local tmp_c:12 = 0;
|
||||
tmp_c[0,31] = opC;
|
||||
local res:12 = tmp_b * tmp_c;
|
||||
MLO = res[0,31];
|
||||
MMID = res[32,31];
|
||||
MHI = res[64,31];
|
||||
}
|
9
Ghidra/Processors/ARC4/data/languages/ARC4_le.slaspec
Normal file
9
Ghidra/Processors/ARC4/data/languages/ARC4_le.slaspec
Normal file
@ -0,0 +1,9 @@
|
||||
# Copyright 2023 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
# Authors: Dan Genin and Tommy Johnson
|
||||
|
||||
define endian=little;
|
||||
|
||||
@define SIZE "4"
|
||||
|
||||
@include "ARC4.sinc"
|
||||
@include "ARC4Instructions.sinc"
|
11
Ghidra/Processors/ARC4/data/patterns/ARC4_LE_patterns.xml
Normal file
11
Ghidra/Processors/ARC4/data/patterns/ARC4_LE_patterns.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<patternlist>
|
||||
<patternpairs totalbits="32" postbits="16">
|
||||
<prepatterns>
|
||||
<data>......00 0x10 0x6e 0x0b</data>
|
||||
</prepatterns>
|
||||
<postpatterns>
|
||||
<data>0x04 0x3e 0x0e 0x10</data>
|
||||
<funcstart/>
|
||||
</postpatterns>
|
||||
</patternpairs>
|
||||
</patternlist>
|
11
Ghidra/Processors/ARC4/data/patterns/ARC4_patterns.xml
Normal file
11
Ghidra/Processors/ARC4/data/patterns/ARC4_patterns.xml
Normal file
@ -0,0 +1,11 @@
|
||||
<patternlist>
|
||||
<patternpairs totalbits="32" postbits="16">
|
||||
<prepatterns>
|
||||
<data>......00 0x10 0x6e 0x0b</data>
|
||||
</prepatterns>
|
||||
<postpatterns>
|
||||
<data>0x04 0x3e 0x0e 0x10</data>
|
||||
<funcstart/>
|
||||
</postpatterns>
|
||||
</patternpairs>
|
||||
</patternlist>
|
@ -0,0 +1,5 @@
|
||||
<patternconstraints>
|
||||
<language id="ARC4:LE:32:*">
|
||||
<patternfile>ARC4_LE_patterns.xml</patternfile>
|
||||
</language>
|
||||
</patternconstraints>
|
0
Ghidra/Processors/ARC4/data/sleighArgs.txt
Normal file
0
Ghidra/Processors/ARC4/data/sleighArgs.txt
Normal file
36
Ghidra/Processors/ARC4/ext.s
Normal file
36
Ghidra/Processors/ARC4/ext.s
Normal file
@ -0,0 +1,36 @@
|
||||
; Copyright 2023 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
; Authors: Dan Genin and Tommy Johnson
|
||||
|
||||
extw r0,r0
|
||||
extw r1,r0
|
||||
extw r0,r1
|
||||
extw r1,r1
|
||||
extb r0,r0
|
||||
extb r1,r0
|
||||
extb r0,r1
|
||||
extb r1,r1
|
||||
nop
|
||||
nop
|
||||
sexw r0,r0
|
||||
sexb r0,r0
|
||||
flag r0
|
||||
.WORD 0x18000000|(0<<9) ; flag
|
||||
.WORD 0x18000000|(1<<9) ; asr
|
||||
.WORD 0x18000000|(2<<9) ; lsr
|
||||
.WORD 0x18000000|(3<<9) ; ror
|
||||
.WORD 0x18000000|(4<<9) ; rrc
|
||||
.WORD 0x18000000|(5<<9) ; sexb
|
||||
.WORD 0x18000000|(6<<9) ; sexw
|
||||
.WORD 0x18000000|(7<<9) ; extb
|
||||
.WORD 0x18000000|(8<<9) ; extw
|
||||
;.WORD 0x18000000|(9<<9) ; illegal instruction
|
||||
;.WORD 0x18000000|(10<<9) ; illegal instruction
|
||||
;.WORD 0x18000000|(11<<9) ; illegal instruction
|
||||
;.WORD 0x18000000|(12<<9) ; illegal instruction
|
||||
;.WORD 0x18000000|(13<<9) ; illegal instruction
|
||||
;.WORD 0x18000000|(14<<9) ; illegal instruction
|
||||
;.WORD 0x18000000|(15<<9) ; illegal instruction
|
||||
;.WORD 0x18000000|(16<<9) ; illegal instruction
|
||||
;.WORD 0x18000000|(17<<9) ; illegal instruction
|
||||
;.WORD 0x18000000|(18<<9) ; illegal instruction
|
||||
;.WORD 0x18000000|(19<<9) ; illegal instruction
|
13
Ghidra/Processors/ARC4/jump.s
Normal file
13
Ghidra/Processors/ARC4/jump.s
Normal file
@ -0,0 +1,13 @@
|
||||
; Copyright 2023 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
; Authors: Dan Genin and Tommy Johnson
|
||||
|
||||
jl.jd 0xfffffff
|
||||
jl blink
|
||||
jl 42
|
||||
jl jl_test
|
||||
.WORD 0x3963120f ; jlpnz [r6]
|
||||
.WORD 0x381f8001 ; j 1 <short immediate>
|
||||
jl_test:
|
||||
nop
|
||||
nop
|
||||
nop
|
23
Ghidra/Processors/ARC4/ld.s
Normal file
23
Ghidra/Processors/ARC4/ld.s
Normal file
@ -0,0 +1,23 @@
|
||||
; Copyright 2023 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
; Authors: Dan Genin and Tommy Johnson
|
||||
|
||||
ld r0, [r1, 1]
|
||||
;; ld r0, [5,4] to (sic) many shimms in load
|
||||
ld r0, [5,5]
|
||||
ld r0, [5]
|
||||
ld r0, [r3]
|
||||
ld r0, [r3, r4]
|
||||
ld r0, [r3, 0x0fffffff]
|
||||
ld r0, [0x0fffffff]
|
||||
;; ld r0, [0x0fffffff, 0x12] ld operand error
|
||||
;; ld.a r0, [5] write-back not permitted
|
||||
ld.a r0, [r1,5]
|
||||
ld.a r0, [r1,-1]
|
||||
ld.a r0, [r1,r2]
|
||||
ld.x r0, [r1]
|
||||
ldw.x r0, [r1]
|
||||
ldb.x r0, [r1]
|
||||
.WORD 0x081f000e ; ld r0, [0x1234, 0xe]
|
||||
.WORD 0x1234 ; supported by objdump but not as
|
||||
.WORD 0x0f126339
|
||||
|
27
Ghidra/Processors/ARC4/logic_ops.s
Normal file
27
Ghidra/Processors/ARC4/logic_ops.s
Normal file
@ -0,0 +1,27 @@
|
||||
; Copyright 2023 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
; Authors: Dan Genin and Tommy Johnson
|
||||
|
||||
asl r0,r1
|
||||
asl r0,42
|
||||
asl r0,0xffffff
|
||||
nop
|
||||
asl 0,r0
|
||||
asl 0,42
|
||||
asl 0,0xfffffff
|
||||
nop
|
||||
and r0,r1,r2
|
||||
and r0,r1,r1
|
||||
and r0,r1,42
|
||||
and r0,r1,0xffffffff
|
||||
and r0,1,4
|
||||
and r0,0xffffffff,r1
|
||||
and r0,1,r1
|
||||
nop
|
||||
and 0,r1,r2
|
||||
and 0,r1,r1
|
||||
and 0,r1,42
|
||||
and 0,r1,0xffffffff
|
||||
and 0,1,4
|
||||
and 0,0xffffffff,r1
|
||||
and 0,1,r1
|
||||
|
42
Ghidra/Processors/ARC4/loop.s
Normal file
42
Ghidra/Processors/ARC4/loop.s
Normal file
@ -0,0 +1,42 @@
|
||||
; mov r2,r0
|
||||
; mov lp_count, 4
|
||||
; lp loop_end
|
||||
;loop_in:
|
||||
; ld r0,[r1]
|
||||
; add r2,r2,r0
|
||||
; add r2,r2,r0
|
||||
;loop_end:
|
||||
; mov r0,r2
|
||||
; j blink
|
||||
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
mov lp_count, 10
|
||||
mov r2,0
|
||||
lp loop1_end
|
||||
loop1_in:
|
||||
ld r0,[r1]
|
||||
add r2,r2,r0
|
||||
add r2,r2,r0
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
loop1_end:
|
||||
mov r0,r2
|
||||
j blink
|
||||
|
||||
mov r2, 0
|
||||
mov lp_count, 5
|
||||
mov r3, loop2_in>>2
|
||||
add r4, r3, 1
|
||||
sr r3, [lp_start]
|
||||
sr r4, [lp_end]
|
||||
;; sr 0x8e, [lp_end]
|
||||
nop
|
||||
nop
|
||||
loop2_in:
|
||||
add r2,r2,r0
|
||||
mov r0, r2
|
||||
j blink
|
2
Ghidra/Processors/ARC4/objdump.sh
Executable file
2
Ghidra/Processors/ARC4/objdump.sh
Executable file
@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
~/other_projects/KodakP720/usr/local/arc/bin/arc-elf32-objdump -D $1
|
14
Ghidra/Processors/ARC4/ret.s
Normal file
14
Ghidra/Processors/ARC4/ret.s
Normal file
@ -0,0 +1,14 @@
|
||||
; Copyright 2023 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
; Authors: Dan Genin and Tommy Johnson
|
||||
|
||||
add r0, r1, r2
|
||||
j blink
|
||||
nop
|
||||
sub r0, r1, 10
|
||||
j 0xFFFF
|
||||
j blink
|
||||
nop
|
||||
add r1, r1, 5
|
||||
sub r0, r1, 10
|
||||
jz 0x10120
|
||||
j blink
|
18
Ghidra/Processors/ARC4/sr.s
Normal file
18
Ghidra/Processors/ARC4/sr.s
Normal file
@ -0,0 +1,18 @@
|
||||
; Copyright 2023 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
; Authors: Dan Genin and Tommy Johnson
|
||||
|
||||
mov r2, 4
|
||||
sr r1,[r2]
|
||||
sr r1,[42]
|
||||
sr r1,[420000]
|
||||
sr 430000,[43]
|
||||
sr 44,[440000]
|
||||
sr 45,[r2]
|
||||
sr 450000,[r2]
|
||||
sr r2, [lp_end]
|
||||
sr r2, [4]
|
||||
sr r2, [5]
|
||||
sr r2, [7]
|
||||
|
||||
lr r0, [r2]
|
||||
j.nd blink
|
13
Ghidra/Processors/ARC4/st.s
Normal file
13
Ghidra/Processors/ARC4/st.s
Normal file
@ -0,0 +1,13 @@
|
||||
; Copyright 2023 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
; Authors: Dan Genin and Tommy Johnson
|
||||
|
||||
st r0, [r1, 1]
|
||||
st r0, [5,5]
|
||||
st r0, [5]
|
||||
st r0, [r3]
|
||||
st 3, [0x0fffffff]
|
||||
st 3, [3]
|
||||
st r0, [0x0fffffff]
|
||||
st.a r0, [r1,5]
|
||||
st.a r0, [r1,-1]
|
||||
|
44
Ghidra/Processors/ARC4/sub.s
Normal file
44
Ghidra/Processors/ARC4/sub.s
Normal file
@ -0,0 +1,44 @@
|
||||
; Copyright 2023 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
; Authors: Dan Genin and Tommy Johnson
|
||||
|
||||
sub r1,r2,32
|
||||
sub r3,r4,32
|
||||
sub r5,r6,32
|
||||
sub r1,ilink1,32
|
||||
sub r1,blink,32
|
||||
sub r1,sp,32
|
||||
sub fp,sp,sp
|
||||
sub sp,r1,sp
|
||||
sub r1,r1,32
|
||||
sub r1,r1,32
|
||||
sub r1,r1,0x1FFFFFFF
|
||||
sub 0x1FFFFFFF,r1,r2
|
||||
|
||||
SUB r1,r2,r3
|
||||
SUB.NZ r1,r2,r3
|
||||
SUB.F r1,r2,r3
|
||||
SUB.NZ.F r1,r2,r3
|
||||
SUB r1,r2,34
|
||||
SUB.F r1,r2,34
|
||||
SUB r1,34,r2
|
||||
SUB r1,255,255
|
||||
SUB.F 0,r1,r2
|
||||
SUB.F 0,r1,34
|
||||
SUB.F 0,34,r1
|
||||
SUB 0,0,0
|
||||
SUB r3,1,2
|
||||
SUB.F r3,1,2
|
||||
|
||||
;; register register
|
||||
;; conditional
|
||||
;; setting flags
|
||||
;;conditional and conditionally set flags
|
||||
;;register immediate
|
||||
;;immediate register
|
||||
;;immediate immediate (shimms MUST match)
|
||||
;;test
|
||||
;;test with immediate
|
||||
;;test with immediate
|
||||
;;null instruction, NOP
|
||||
|
||||
|
BIN
Ghidra/Processors/ARC4/test
Executable file
BIN
Ghidra/Processors/ARC4/test
Executable file
Binary file not shown.
28
Ghidra/Processors/ARC4/test.s
Normal file
28
Ghidra/Processors/ARC4/test.s
Normal file
@ -0,0 +1,28 @@
|
||||
; Copyright 2023 The Johns Hopkins University Applied Physics Laboratory LLC
|
||||
; Authors: Dan Genin and Tommy Johnson
|
||||
|
||||
.ORG 0x100
|
||||
.include "add.s"
|
||||
nop
|
||||
.include "branch.s"
|
||||
nop
|
||||
.include "jump.s"
|
||||
nop
|
||||
.include "ext.s"
|
||||
nop
|
||||
.include "loop.s"
|
||||
nop
|
||||
.include "sr.s"
|
||||
nop
|
||||
.include "st.s"
|
||||
nop
|
||||
.include "ld.s"
|
||||
nop
|
||||
.include "ret.s"
|
||||
nop
|
||||
.include "add.s"
|
||||
nop
|
||||
.include "sub.s"
|
||||
nop
|
||||
.include "logic_ops.s"
|
||||
nop
|
Loading…
Reference in New Issue
Block a user