From 02d827b859e47aa2bec542d26168099765b3212c Mon Sep 17 00:00:00 2001 From: James <49045138+ghidracadabra@users.noreply.github.com> Date: Sat, 9 Oct 2021 18:42:44 +0000 Subject: [PATCH] GP-1378 make add with carry/subtract with borrow macros decompiler-friendly --- .../data/languages/ARMTHUMBinstructions.sinc | 25 +++++++---- .../ARM/data/languages/ARMinstructions.sinc | 43 +++++++++++-------- .../Sparc/data/languages/SparcV9.sinc | 26 ++++------- 3 files changed, 49 insertions(+), 45 deletions(-) diff --git a/Ghidra/Processors/ARM/data/languages/ARMTHUMBinstructions.sinc b/Ghidra/Processors/ARM/data/languages/ARMTHUMBinstructions.sinc index e68be097dc..b388ae9248 100644 --- a/Ghidra/Processors/ARM/data/languages/ARMTHUMBinstructions.sinc +++ b/Ghidra/Processors/ARM/data/languages/ARMTHUMBinstructions.sinc @@ -215,14 +215,21 @@ macro th_addflags(op1,op2) { #See ARM Architecture reference section "Pseudocode details of addition and subtraction" macro th_add_with_carry_flags(op1,op2){ -local CYz = zext(CY); -local CYa = carry( op1, op2 ); -local OVa = scarry( op1, op2 ); -local result = op1 + op2; -tmpCY = CYa || carry( result, CYz ); -tmpOV = OVa ^^ scarry( result, CYz ); + local CYz = zext(CY); + local result = op1 + op2; + tmpCY = carry( op1, op2 ) || carry( result, CYz ); + tmpOV = scarry( op1, op2) ^^ scarry( result, CYz ); } +#Note: used for subtraction op1 - (op2 + !CY) +#sets tmpCY if there is NO borrow +macro th_sub_with_carry_flags(op1, op2){ + local result = op1 - op2; + tmpCY = (op1 > op2) || (result < zext(CY)); + tmpOV = sborrow(op1,op2) ^^ sborrow(result,zext(!CY)); +} + + macro th_test_flags(result){ ZR = (result == 0); NG = (result s< 0); @@ -3688,7 +3695,7 @@ macro th_set_carry_for_ror(result, count) { :sbc^CheckInIT_CZNO^ItCond Rd0002,Rm0305 is TMode=1 & ItCond & op6=0x106 & Rm0305 & Rd0002 & CheckInIT_CZNO { build ItCond; - th_add_with_carry_flags(Rd0002,~Rm0305); + th_sub_with_carry_flags(Rd0002,Rm0305); Rd0002 = Rd0002 - Rm0305 - zext(!CY); resflags(Rd0002); build CheckInIT_CZNO; @@ -3700,7 +3707,7 @@ macro th_set_carry_for_ror(result, count) { { build ItCond; build ThumbExpandImm12; - th_add_with_carry_flags(Rn0003,~ThumbExpandImm12); + th_sub_with_carry_flags(Rn0003,ThumbExpandImm12); Rd0811 = Rn0003 - ThumbExpandImm12 - zext(!CY); resflags(Rd0811); build thSBIT_CZNO; @@ -3710,7 +3717,7 @@ macro th_set_carry_for_ror(result, count) { { build ItCond; build thshift2; - th_add_with_carry_flags(Rn0003,~thshift2); + th_sub_with_carry_flags(Rn0003,thshift2); Rd0811 = Rn0003 - thshift2 - zext(!CY); resflags(Rd0811); build thSBIT_CZNO; diff --git a/Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc b/Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc index 138f30ccd3..61cd24752b 100644 --- a/Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc +++ b/Ghidra/Processors/ARM/data/languages/ARMinstructions.sinc @@ -1878,14 +1878,21 @@ SetMode: "#"^31 is c0004=0x1f { setSystemMode(); } #See ARM Architecture reference section "Pseudocode details of addition and subtraction" macro add_with_carry_flags(op1,op2){ -local CYz = zext(CY); -local CYa = carry( op1, op2 ); -local OVa = scarry( op1, op2 ); -local result = op1 + op2; -tmpCY = CYa || carry( result, CYz ); -tmpOV = OVa ^^ scarry( result, CYz ); + local CYz = zext(CY); + local result = op1 + op2; + tmpCY = carry( op1, op2) || carry( result, CYz ); + tmpOV = scarry( op1, op2 ) ^^ scarry( result, CYz ); } +#Note: used for subtraction op1 - (op2 + !CY) +#sets tmpCY if there is NO borrow +macro sub_with_carry_flags(op1, op2){ + local result = op1 - op2; + tmpCY = (op1 > op2) || (result < zext(CY)); + tmpOV = sborrow(op1,op2) ^^ sborrow(result,zext(!CY)); +} + + :adc^COND^SBIT_CZNO Rd,rn,shift1 is $(AMODE) & COND & c2124=5 & SBIT_CZNO & rn & Rd & c2627=0 & shift1 { build COND; @@ -4653,7 +4660,7 @@ macro BitReverse_arm(val) { build COND; build rn; build shift1; - add_with_carry_flags(~rn,shift1); + sub_with_carry_flags(shift1,rn); Rd=shift1-(rn+zext(!CY)); resultflags(Rd); build SBIT_CZNO; @@ -4664,7 +4671,7 @@ macro BitReverse_arm(val) { build COND; build rn; build shift2; - add_with_carry_flags(~rn,shift2); + sub_with_carry_flags(shift2,rn); Rd=shift2-(rn+zext(!CY)); resultflags(Rd); build SBIT_CZNO; @@ -4675,7 +4682,7 @@ macro BitReverse_arm(val) { build COND; build rn; build shift3; - add_with_carry_flags(~rn,shift3); + sub_with_carry_flags(shift3,rn); Rd=shift3-(rn+zext(!CY)); resultflags(Rd); build SBIT_CZNO; @@ -4686,7 +4693,7 @@ macro BitReverse_arm(val) { build COND; build rn; build shift1; - add_with_carry_flags(~rn,shift1); + sub_with_carry_flags(shift1,rn); local dest:4=shift1-(rn+zext(!CY)); resultflags(dest); build SBIT_CZNO; @@ -4699,7 +4706,7 @@ macro BitReverse_arm(val) { build COND; build rn; build shift2; - add_with_carry_flags(~rn,shift2); + sub_with_carry_flags(shift2,rn); local dest:4=shift2-(rn + zext(!CY)); resultflags(dest); build SBIT_CZNO; @@ -4712,7 +4719,7 @@ macro BitReverse_arm(val) { build COND; build rn; build shift3; - add_with_carry_flags(~rn,shift3); + sub_with_carry_flags(shift3,rn); local dest:4=shift3-(rn + zext(!CY)); resultflags(dest); build SBIT_CZNO; @@ -4785,7 +4792,7 @@ macro BitReverse_arm(val) { build COND; build rn; build shift1; - add_with_carry_flags(rn,~shift1); + sub_with_carry_flags(rn,shift1); Rd = rn-(shift1+zext(!CY)); resultflags(Rd); build SBIT_CZNO; @@ -4796,7 +4803,7 @@ macro BitReverse_arm(val) { build COND; build rn; build shift2; - add_with_carry_flags(rn,~shift2); + sub_with_carry_flags(rn,shift2); Rd = rn-(shift2 + zext(!CY)); resultflags(Rd); build SBIT_CZNO; @@ -4807,7 +4814,7 @@ macro BitReverse_arm(val) { build COND; build rn; build shift3; - add_with_carry_flags(rn,~shift3); + sub_with_carry_flags(rn,shift3); Rd = rn-(shift3+zext(!CY)); resultflags(Rd); build SBIT_CZNO; @@ -4818,7 +4825,7 @@ macro BitReverse_arm(val) { build COND; build rn; build shift1; - add_with_carry_flags(rn,~shift1); + sub_with_carry_flags(rn,shift1); local dest:4 = rn-(shift1 + zext(!CY)); resultflags(dest); build SBIT_CZNO; @@ -4831,7 +4838,7 @@ macro BitReverse_arm(val) { build COND; build rn; build shift2; - add_with_carry_flags(rn,~shift2); + sub_with_carry_flags(rn,shift2); local dest:4 = rn-(shift2+zext(!CY)); resultflags(dest); build SBIT_CZNO; @@ -4844,7 +4851,7 @@ macro BitReverse_arm(val) { build COND; build rn; build shift3; - add_with_carry_flags(rn,~shift3); + sub_with_carry_flags(rn,shift3); local dest:4 = rn-(shift3 + zext(!CY)); resultflags(dest); build SBIT_CZNO; diff --git a/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc b/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc index 67acc2054a..314f243dc6 100644 --- a/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc +++ b/Ghidra/Processors/Sparc/data/languages/SparcV9.sinc @@ -408,34 +408,24 @@ macro addCarryFlags ( op1, op2 ) { local op1_low_32:4 = op1:4; local op2_low_32:4 = op2:4; local CFcopy:$(SIZE) = zext(i_cf); - local CFcopy_32:4 = zext(i_cf); - i_cf = carry( op1_low_32, op2_low_32); - x_cf = carry(op1,op2); - i_vf = scarry( op1_low_32, op2_low_32); - x_vf = scarry(op1, op2); local result:$(SIZE) = op1 + op2; local result_low_32:4 = op1_low_32 + op2_low_32; - i_cf = i_cf || carry( result_low_32, CFcopy_32 ); - x_cf = x_cf || carry(result,CFcopy); - i_vf = i_vf ^^ scarry( result_low_32, CFcopy_32 ); - x_vf = x_vf ^^ scarry(result,CFcopy); + i_cf = carry( op1_low_32, op2_low_32) || carry( result_low_32, CFcopy:4 ); + x_cf = carry(op1,op2) || carry(result,CFcopy); + i_vf = scarry( op1_low_32, op2_low_32) ^^ scarry( result_low_32, CFcopy:4 ); + x_vf = scarry(op1, op2) ^^ scarry(result,CFcopy); } macro subCarryFlags ( op1, op2 ) { local op1_low_32:4 = op1:4; local op2_low_32:4 = op2:4; local CFcopy:$(SIZE) = zext(i_cf); - local CFCopy_32:4 = zext(i_cf); - i_cf = op1_low_32 < op2_low_32; - x_cf = op1 < op2; - i_vf = sborrow( op1_low_32, op2_low_32); - x_vf = sborrow(op1, op2); local result:$(SIZE) = op1 - op2; local result_low_32:4 = op1_low_32 - op2_low_32; - i_cf = i_cf || (result_low_32 < CFCopy_32); - x_cf = x_cf || (result < CFcopy); - i_vf = i_vf ^^ sborrow( result_low_32, CFCopy_32); - x_vf = x_vf ^^ sborrow(result,CFcopy); + i_cf = (op1_low_32 < op2_low_32) || (result_low_32 < CFcopy:4); + x_cf = (op1 < op2) || (result < CFcopy); + i_vf = sborrow( op1_low_32, op2_low_32) ^^ sborrow( result_low_32, CFcopy:4); + x_vf = sborrow(op1, op2) ^^ sborrow(result,CFcopy); } macro logicflags() {