ghidra/Ghidra/Processors/Toy/data/languages/toy_builder.sinc

87 lines
2.7 KiB
Plaintext

@include "toy.sinc"
# Define context bits
define register offset=0x2000 size=8 contextreg;
define context contextreg
# stored context
fctx = (0,3) # flowing context
nfctx = (4,7) noflow # single address context
# transient context (never stored, aids disassembly)
phase = (8,9) # parse phase - used for complex scenarios
counter = (10,13) # parse count-down
;
define token instr8(8)
op8 = (0, 7)
;
define token extra16(16)
xsimm8 = (0, 7) signed
;
define token extra8(8)
nnnn = (0, 3)
;
# ^instruction - manage parse phases (only required for complex languages)
:^instruction is phase=0 & instruction [ phase=1; ] { build instruction; }
@define INSTR_PHASE "phase=1 &" # parse instructions during phase 1
@include "toyInstructions.sinc"
# additional forms added to toy language, taken from all three reserved banks:
# 1101 1001 xxxx xxxx # RESERVED BANK
# 1101 1010 xxxx xxxx # RESERVED BANK
# 1111 0111 xxxx xxxx # RESERVED BANK
# fctx i 1101 1001 0000 iiii # set flow context (fctx) on next instr
# nfctx i 1101 1001 0001 iiii # set noflow context (nfctx) on next instr
# nfctx rel,i 1101 1001 0010 iiii; 0000 0000 iiii iiii # set noflow context on rel instr
# cop# s 1101 1010 ssss 0000 # coprocessor # determined by nfctx val (1-3)
# nop #1 1111 0111
# nop #<n+2> 1101 1001 0011 nnnn; ... # nop where nnnn indicates number of additional bytes consumed
# operations
:fctx Imm4 is phase=1 & op1215=0xd & op0811=0x9 & rs=0x0 & imm0003 & Imm4 [ fctx=imm0003; globalset(inst_next,fctx); ] { }
nfctxSetAddr: addr is Imm4 & imm0003; xsimm8 [ addr = inst_start + xsimm8; nfctx=imm0003; globalset(addr, nfctx); ] { export *:$(SIZE) addr; }
:nfctx nfctxSetAddr,Imm4 is (phase=1 & op1215=0xd & op0811=0x9 & rs=0x2 & Imm4) ... & nfctxSetAddr { }
:nfctx Imm4 is phase=1 & op1215=0xd & op0811=0x9 & rs=0x1 & imm0003 & Imm4 [ nfctx=imm0003; globalset(inst_next,nfctx); ] { }
define pcodeop cop1;
define pcodeop cop2;
define pcodeop cop3;
:cop1 rs is phase=1 & op1215=0xd & op0811=0xa & op0003=0 & nfctx=1 & rs { cop1(rs); }
:cop2 rs is phase=1 & op1215=0xd & op0811=0xa & op0003=0 & nfctx=2 & rs { cop2(rs); }
:cop3 rs is phase=1 & op1215=0xd & op0811=0xa & op0003=0 & nfctx=3 & rs { cop3(rs); }
NopCnt: "#"^cnt is imm0003 [ cnt = imm0003 + 2; ] { export *[const]:1 cnt; }
NopByte: is counter=0 { }
NopByte: is epsilon; nnnn; NopByte [ counter=counter-1; ] { }
One: "#"^cnt is epsilon [ cnt = 1; ] { export *[const]:1 cnt; }
:nop One is phase=1 & op8=0xf7 & One { }
:nop NopCnt is phase=1 & op1215=0xd & op0811=0x9 & rs=0x3 & imm0003 & NopCnt; NopByte ... [ counter=imm0003; ] { }