mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-21 18:31:34 +08:00
Merge remote-tracking branch 'origin/GT-3276_ghidorahrex_avr8_flag_fixup'
This commit is contained in:
@@ -354,63 +354,27 @@ macro setSflag() {
|
||||
}
|
||||
|
||||
macro setResultFlags(result) {
|
||||
$(Nflag) = (result & 0x80) == 0x80;
|
||||
$(Nflag) = (result s< 0);
|
||||
$(Zflag) = (result == 0x0);
|
||||
setSflag();
|
||||
}
|
||||
|
||||
macro setResult16Flags(result) {
|
||||
$(Nflag) = (result & 0x8000) == 0x8000;
|
||||
$(Zflag) = (result == 0x0);
|
||||
setSflag();
|
||||
}
|
||||
|
||||
macro setSubCarry(pre,sub) { # pre - sub
|
||||
$(Cflag) = (pre < sub);
|
||||
}
|
||||
|
||||
# The decompilation looks better when the pcode comparision is used,
|
||||
# rather than walking though the bit examples in the manual.
|
||||
# todo: consolidate these
|
||||
macro setVflagForSub(pre,sub,res) { # res = pre - sub
|
||||
$(Vflag) = sborrow(pre,sub);
|
||||
}
|
||||
|
||||
macro setVflagForSub16(pre,sub) { # pre - sub
|
||||
$(Vflag) = sborrow(pre,sub);
|
||||
}
|
||||
|
||||
macro setVflagForAdd(arg1,arg2,res) {
|
||||
local a = (arg1 & 0x80) >> 7;
|
||||
local b = (arg2 & 0x80) >> 7;
|
||||
local c = (res & 0x80) >> 7;
|
||||
local V = (a & b & (~c)) | ((~a) & (~b) & c);
|
||||
$(Vflag) = V & 0x01;
|
||||
}
|
||||
|
||||
macro setCflagForAdd(arg1,arg2,res) {
|
||||
local a = (arg1 & 0x80) >> 7;
|
||||
local b = (arg2 & 0x80) >> 7;
|
||||
local c = (res & 0x80) >> 7;
|
||||
local V = (a & b) | (a & (~c)) | (b & (~c));
|
||||
$(Cflag) = V & 0x01;
|
||||
}
|
||||
|
||||
macro doSubtract(pre,sub,res) {
|
||||
local x = pre - sub;
|
||||
setVflagForSub(pre,sub,x);
|
||||
setSubCarry(pre, sub);
|
||||
$(Vflag) = sborrow(pre,sub);
|
||||
$(Cflag) = (pre < sub);
|
||||
setResultFlags(x);
|
||||
$(Sflag) = pre s< sub;
|
||||
res = x;
|
||||
}
|
||||
|
||||
macro doSubtractWithCarry(pre,subNoCarry,res) {
|
||||
local sub = subNoCarry + $(Cflag);
|
||||
local x = pre - sub;
|
||||
macro doSubtractWithCarry(pre,sub,res) {
|
||||
local partial = pre - sub;
|
||||
local subCarry = sub + $(Cflag);
|
||||
local x = pre - subCarry;
|
||||
local oldZflag = $(Zflag);
|
||||
setVflagForSub(pre,subNoCarry,x);
|
||||
$(Cflag) = ((pre < sub) | (sub == 0 & $(Cflag) == 1));
|
||||
$(Vflag) = sborrow(pre,sub) ^^ sborrow(partial, $(Cflag));
|
||||
$(Cflag) = (pre < sub) || (partial < $(Cflag));
|
||||
setResultFlags(x);
|
||||
$(Sflag) = $(Nflag)^$(Vflag);
|
||||
$(Zflag) = oldZflag & $(Zflag);
|
||||
@@ -491,7 +455,7 @@ K7addr: val is oplow4 & op9to10 & opbit8 [ val = ((1 ^ opbit8) << 7) | (opbit8
|
||||
|
||||
# Join against various spaces for dataspace...
|
||||
# #####################################################################################
|
||||
# COMMENTING OUT BECAUSE "Subtable symbol K7addr is not allowed in context block"
|
||||
# COMMENTING OUT BECAUSE "subtable symbol K7addr is not allowed in context block"
|
||||
#K7Ioaddr: val is K7addr [ val = K7addr - 0x20; ] { tmp:1 = val; export tmp; }
|
||||
# #####################################################################################
|
||||
# COMMENTING OUT BECAUSE "Subtable symbol K7Ioaddr is not allowed in context block"
|
||||
@@ -536,26 +500,28 @@ define pcodeop break;
|
||||
@ifdef FUSION
|
||||
# add followed by adc
|
||||
:addw op1RdPair,op1RrPair is phase=1 & op1hi6=0x3 & op2hi6=0x7 & op1RdPair & op1RrPair & fusion16rrrrPred {
|
||||
$(Cflag) = carry(op1RdPair,op1RrPair);
|
||||
local pre = op1RdPair;
|
||||
local post = op1RdPair + op1RrPair;
|
||||
$(Cflag) = carry(op1RdPair,op1RrPair);
|
||||
$(Vflag) = scarry(pre,op1RrPair);
|
||||
op1RdPair = post;
|
||||
$(Vflag) = (0x0000 == (pre & 0x8000)) & ((post & 0x8000) == 0x8000);
|
||||
setResult16Flags(post);
|
||||
setResultFlags(post);
|
||||
}
|
||||
|
||||
@endif
|
||||
# Rd,Rr
|
||||
:adc RdFull,RrFull is phase=1 & ophi6=0x7 & RdFull & RrFull {
|
||||
local res = RdFull + RrFull + $(Cflag);
|
||||
setCflagForAdd(RdFull,RrFull,res);
|
||||
$(Cflag) = carry(RdFull, RrFull) || carry(RdFull + RrFull, $(Cflag));
|
||||
$(Vflag) = scarry(RdFull, RrFull) ^^ scarry(RdFull + RrFull, $(Cflag));
|
||||
setResultFlags(res);
|
||||
RdFull = res;
|
||||
}
|
||||
# Rd,Rr
|
||||
:add RdFull,RrFull is phase=1 & ophi6=0x3 & RdFull & RrFull {
|
||||
local res = RdFull + RrFull;
|
||||
setCflagForAdd(RdFull,RrFull,res);
|
||||
$(Cflag) = carry(RdFull,RrFull);
|
||||
$(Vflag) = scarry(RdFull,RrFull);
|
||||
setResultFlags(res);
|
||||
RdFull = res;
|
||||
}
|
||||
@@ -564,8 +530,8 @@ define pcodeop break;
|
||||
local pre = Rdw2;
|
||||
Rdw2 = Rdw2 + zext(K6);
|
||||
$(Cflag) = carry(pre,zext(K6));
|
||||
$(Vflag) = scarry(Rdw2,zext(K6)); #(0x0000 == (pre & 0x8000)) & ((Rdw2 & 0x8000) == 0x8000);
|
||||
setResult16Flags(Rdw2);
|
||||
$(Vflag) = scarry(Rdw2,zext(K6));
|
||||
setResultFlags(Rdw2);
|
||||
}
|
||||
# and Rd,Rr
|
||||
:and RdFull,RrFull is phase=1 & ophi6=8 & RdFull & RrFull {
|
||||
@@ -674,8 +640,8 @@ define pcodeop break;
|
||||
}
|
||||
:cp RdFull,RrFull is phase=1 & ophi6=0x05 & RdFull & RrFull {
|
||||
local x = RdFull - RrFull;
|
||||
setSubCarry(RdFull,RrFull);
|
||||
setVflagForSub(RdFull,RrFull,x);
|
||||
$(Cflag) = (RdFull < RrFull);
|
||||
$(Vflag) = sborrow(RdFull,RrFull);
|
||||
setResultFlags(x);
|
||||
# but doesn't set result into a register
|
||||
}
|
||||
@@ -700,9 +666,9 @@ define pcodeop break;
|
||||
# cp; cpc sequence
|
||||
:cpw op1RdPair,op1RrPair phase=1 & is op1hi6=0x5 & op2hi6=0x1 & fusion16rrrrPred & op1RdPair & op1RrPair {
|
||||
local res = op1RdPair - op1RrPair;
|
||||
setVflagForSub16(op1RdPair,op1RrPair);
|
||||
setSubCarry(op1RdPair, op1RrPair);
|
||||
setResult16Flags(res);
|
||||
$(Vflag) = sborrow(op1RdPair,op1RrPair);
|
||||
$(Cflag) = (op1RdPair < op1RrPair);
|
||||
setResultFlags(res);
|
||||
$(Sflag) = op1RdPair s< op1RrPair;
|
||||
}
|
||||
|
||||
@@ -1035,10 +1001,10 @@ LpmPlus: Z^"+" is Z {}
|
||||
# doSubtract(op1RdPairHi,K16fuse,op1RdPairHi);
|
||||
local res = op1RdPairHi - K16fuse;
|
||||
local pre = op1RdPairHi;
|
||||
setVflagForSub16(pre,K16fuse);
|
||||
setSubCarry(op1RdPairHi, K16fuse);
|
||||
$(Vflag) = sborrow(pre,K16fuse);
|
||||
$(Cflag) = (op1RdPairHi < K16fuse);
|
||||
op1RdPairHi = res;
|
||||
setResult16Flags(res);
|
||||
setResultFlags(res);
|
||||
$(Sflag) = pre s< K16fuse;
|
||||
}
|
||||
|
||||
@@ -1057,9 +1023,9 @@ LpmPlus: Z^"+" is Z {}
|
||||
:sbiw Rdw2,K6 is phase=1 & ophi8=0x97 & Rdw2 & K6 {
|
||||
local pre = Rdw2;
|
||||
Rdw2 = Rdw2 - zext(K6);
|
||||
$(Cflag) = zext(K6) > pre;
|
||||
$(Vflag) = (0x8000 == (pre & 0x8000)) & ((Rdw2 & 0x8000) == 0x0000);
|
||||
setResult16Flags(Rdw2);
|
||||
$(Cflag) = (pre < zext(K6));
|
||||
$(Vflag) = sborrow(pre,zext(K6));
|
||||
setResultFlags(Rdw2);
|
||||
}
|
||||
# sbr is an alias for ori
|
||||
|
||||
|
||||
Reference in New Issue
Block a user