Merge remote-tracking branch 'origin/GT-3276_ghidorahrex_avr8_flag_fixup'

This commit is contained in:
ghidorahrex
2020-03-18 13:58:04 -04:00
@@ -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