mirror of
https://github.com/capstone-engine/capstone.git
synced 2025-02-01 03:23:59 +00:00
[TriCore] Replace one- and sign-extend with MathExtra.h functions. (#2212)
* Replace one- and sign-extend with MathExtra.h functions. This fixes incorrect sign extensions and reachable aborts(). * Wrap around PC relative values instead of abort in case of overflow. --------- Co-authored-by: billow <billow.fun@gmail.com>
This commit is contained in:
parent
d54934201c
commit
2fa9f60dcc
16
MathExtras.h
16
MathExtras.h
@ -416,16 +416,32 @@ static inline int64_t abs64(int64_t x) {
|
||||
|
||||
/// \brief Sign extend number in the bottom B bits of X to a 32-bit int.
|
||||
/// Requires 0 < B <= 32.
|
||||
/// Note that this implementation relies on right shift of signed
|
||||
/// integers being an arithmetic shift.
|
||||
static inline int32_t SignExtend32(uint32_t X, unsigned B) {
|
||||
return (int32_t)(X << (32 - B)) >> (32 - B);
|
||||
}
|
||||
|
||||
/// \brief Sign extend number in the bottom B bits of X to a 64-bit int.
|
||||
/// Requires 0 < B <= 64.
|
||||
/// Note that this implementation relies on right shift of signed
|
||||
/// integers being an arithmetic shift.
|
||||
static inline int64_t SignExtend64(uint64_t X, unsigned B) {
|
||||
return (int64_t)(X << (64 - B)) >> (64 - B);
|
||||
}
|
||||
|
||||
/// \brief One extend number X starting at bit B and returns it as int32_t.
|
||||
/// Requires 0 < B <= 32.
|
||||
static inline int32_t OneExtend32(uint32_t X, unsigned B) {
|
||||
return (~0U << B) | X;
|
||||
}
|
||||
|
||||
/// \brief One extend number X starting at bit B and returns it as int64_t.
|
||||
/// Requires 0 < B <= 64.
|
||||
static inline int64_t OneExtend64(uint64_t X, unsigned B) {
|
||||
return (~0ULL << B) | X;
|
||||
}
|
||||
|
||||
/// \brief Count number of 0's from the most significant bit to the least
|
||||
/// stopping at the first 1.
|
||||
///
|
||||
|
@ -39,38 +39,12 @@ static void printOperand(MCInst *MI, int OpNum, SStream *O);
|
||||
|
||||
#include "TriCoreGenRegisterInfo.inc"
|
||||
|
||||
static uint32_t to_u32(int64_t x)
|
||||
static uint32_t wrapping_u32(int64_t x)
|
||||
{
|
||||
if (x > UINT32_MAX || x < -(int64_t)(UINT32_MAX)) {
|
||||
abort();
|
||||
}
|
||||
x %= (int64_t)(UINT32_MAX);
|
||||
return (uint32_t)x;
|
||||
}
|
||||
|
||||
static inline unsigned int get_msb(uint64_t value)
|
||||
{
|
||||
unsigned int msb = 0;
|
||||
while (value > 0) {
|
||||
value >>= 1; // Shift bits to the right
|
||||
msb++; // Increment the position of the MSB
|
||||
}
|
||||
return msb;
|
||||
}
|
||||
|
||||
static inline int64_t sign_ext64(int64_t imm, unsigned n)
|
||||
{
|
||||
n = get_msb(imm) > n ? get_msb(imm) : n;
|
||||
int64_t mask = 1 << (n - 1);
|
||||
return (imm ^ mask) - mask;
|
||||
}
|
||||
|
||||
static inline int32_t sign_ext32(int32_t imm, unsigned n)
|
||||
{
|
||||
n = get_msb(imm) > n ? get_msb(imm) : n;
|
||||
int32_t mask = 1 << (n - 1);
|
||||
return (imm ^ mask) - mask;
|
||||
}
|
||||
|
||||
static bool fill_mem(MCInst *MI, unsigned int reg, int64_t disp);
|
||||
|
||||
static inline void set_mem(cs_tricore_op *op, uint8_t base, int64_t disp)
|
||||
@ -193,7 +167,7 @@ static void printOperand(MCInst *MI, int OpNum, SStream *O)
|
||||
fill_reg(MI, reg);
|
||||
} else if (MCOperand_isImm(Op)) {
|
||||
int64_t Imm = MCOperand_getImm(Op);
|
||||
printUInt32Bang(O, to_u32(Imm));
|
||||
printUInt32Bang(O, wrapping_u32(Imm));
|
||||
fill_imm(MI, Imm);
|
||||
}
|
||||
}
|
||||
@ -203,7 +177,7 @@ static void print_sign_ext(MCInst *MI, int OpNum, SStream *O, unsigned n)
|
||||
MCOperand *MO = MCInst_getOperand(MI, OpNum);
|
||||
if (MCOperand_isImm(MO)) {
|
||||
int64_t imm = MCOperand_getImm(MO);
|
||||
int32_t res = sign_ext32(to_u32(imm), n);
|
||||
int32_t res = SignExtend32(wrapping_u32(imm), n);
|
||||
printInt32Bang(O, res);
|
||||
fill_imm(MI, res);
|
||||
} else
|
||||
@ -262,7 +236,7 @@ static void print_zero_ext(MCInst *MI, int OpNum, SStream *O, unsigned n)
|
||||
const8_fixup(MI, &imm);
|
||||
}
|
||||
|
||||
printUInt32Bang(O, to_u32(imm));
|
||||
printUInt32Bang(O, wrapping_u32(imm));
|
||||
fill_imm(MI, imm);
|
||||
} else
|
||||
printOperand(MI, OpNum, O);
|
||||
@ -273,17 +247,18 @@ static void printOff18Imm(MCInst *MI, int OpNum, SStream *O)
|
||||
MCOperand *MO = MCInst_getOperand(MI, OpNum);
|
||||
if (MCOperand_isImm(MO)) {
|
||||
int64_t imm = MCOperand_getImm(MO);
|
||||
imm = ((to_u32(imm) & 0x3C000) << 14) | (to_u32(imm) & 0x3fff);
|
||||
printUInt32Bang(O, to_u32(imm));
|
||||
imm = ((wrapping_u32(imm) & 0x3C000) << 14) |
|
||||
(wrapping_u32(imm) & 0x3fff);
|
||||
printUInt32Bang(O, wrapping_u32(imm));
|
||||
fill_imm(MI, imm);
|
||||
} else
|
||||
printOperand(MI, OpNum, O);
|
||||
}
|
||||
|
||||
// PC + sext(2 * disp)
|
||||
#define DISP1(N) ((int64_t)(MI->address) + sign_ext64(disp * 2, N))
|
||||
#define DISP1(N) ((int64_t)(MI->address) + SignExtend64(disp * 2, N))
|
||||
// PC + sext(disp) * 2
|
||||
#define DISP2(N) ((int64_t)(MI->address) + sign_ext64(disp, N) * 2)
|
||||
#define DISP2(N) ((int64_t)(MI->address) + SignExtend64(disp, N) * 2)
|
||||
|
||||
static void printDisp24Imm(MCInst *MI, int OpNum, SStream *O)
|
||||
{
|
||||
@ -302,8 +277,8 @@ static void printDisp24Imm(MCInst *MI, int OpNum, SStream *O)
|
||||
case TRICORE_JA_b:
|
||||
case TRICORE_JLA_b:
|
||||
// = {disp24[23:20], 7’b0000000, disp24[19:0], 1’b0};
|
||||
res = ((to_u32(disp) & 0xf00000) << 28) |
|
||||
((to_u32(disp) & 0xfffff) << 1);
|
||||
res = ((wrapping_u32(disp) & 0xf00000) << 28) |
|
||||
((wrapping_u32(disp) & 0xfffff) << 1);
|
||||
break;
|
||||
case TRICORE_J_b:
|
||||
case TRICORE_JL_b:
|
||||
@ -311,7 +286,7 @@ static void printDisp24Imm(MCInst *MI, int OpNum, SStream *O)
|
||||
break;
|
||||
}
|
||||
|
||||
printUInt32Bang(O, to_u32(res));
|
||||
printUInt32Bang(O, wrapping_u32(res));
|
||||
fill_imm(MI, res);
|
||||
} else
|
||||
printOperand(MI, OpNum, O);
|
||||
@ -357,7 +332,7 @@ static void printDisp15Imm(MCInst *MI, int OpNum, SStream *O)
|
||||
break;
|
||||
}
|
||||
|
||||
printUInt32Bang(O, to_u32(res));
|
||||
printUInt32Bang(O, wrapping_u32(res));
|
||||
fill_imm(MI, res);
|
||||
} else
|
||||
printOperand(MI, OpNum, O);
|
||||
@ -383,7 +358,7 @@ static void printDisp8Imm(MCInst *MI, int OpNum, SStream *O)
|
||||
break;
|
||||
}
|
||||
|
||||
printUInt32Bang(O, to_u32(res));
|
||||
printUInt32Bang(O, wrapping_u32(res));
|
||||
fill_imm(MI, res);
|
||||
} else
|
||||
printOperand(MI, OpNum, O);
|
||||
@ -422,16 +397,15 @@ static void printDisp4Imm(MCInst *MI, int OpNum, SStream *O)
|
||||
break;
|
||||
case TRICORE_LOOP_sbr:
|
||||
// PC + {27b’111111111111111111111111111, disp4, 0};
|
||||
res = (int64_t)(MI->address) +
|
||||
((0b111111111111111111111111111LL << 5) |
|
||||
(to_u32(disp) << 1));
|
||||
res = (int64_t)MI->address +
|
||||
OneExtend32(wrapping_u32(disp) << 1, 5);
|
||||
break;
|
||||
default:
|
||||
// handle other cases, if any
|
||||
break;
|
||||
}
|
||||
|
||||
printUInt32Bang(O, to_u32(res));
|
||||
printUInt32Bang(O, wrapping_u32(res));
|
||||
fill_imm(MI, res);
|
||||
} else
|
||||
printOperand(MI, OpNum, O);
|
||||
@ -476,10 +450,9 @@ static void printOExtImm_4(MCInst *MI, int OpNum, SStream *O)
|
||||
MCOperand *MO = MCInst_getOperand(MI, OpNum);
|
||||
if (MCOperand_isImm(MO)) {
|
||||
int64_t disp = MCOperand_getImm(MO);
|
||||
int64_t res = (int64_t)(MI->address) +
|
||||
((0b111111111111111111111111111 << 5) |
|
||||
(to_u32(disp) << 1));
|
||||
printUInt32Bang(O, to_u32(res));
|
||||
int64_t res = (int64_t)MI->address +
|
||||
(int64_t)OneExtend64(disp << 1, 5);
|
||||
printUInt32Bang(O, wrapping_u32(res));
|
||||
fill_imm(MI, res);
|
||||
} else
|
||||
printOperand(MI, OpNum, O);
|
||||
|
@ -62,7 +62,7 @@
|
||||
0xf6,0x24 = jnz d2, #0x8
|
||||
0xfc,0xf6 = loop a15, #-0x14
|
||||
0x37,0x00,0x62,0xfe = extr.u d15, d0, #0x1c, #0x2
|
||||
0x6d,0xb8,0xf4,0x11 = call #-0x8fdc18
|
||||
0x6d,0xb8,0xf4,0x11 = call #0x7023e8
|
||||
0x91,0x00,0x03,0xfa = movh.a a15, #0xa030
|
||||
0x3b,0x20,0xfe,0x0f = mov d0, #-0x1e
|
||||
0x37,0x00,0x61,0x03 = extr.u d0, d0, #0x6, #0x1
|
||||
@ -122,7 +122,7 @@
|
||||
0x91,0x10,0x00,0xa4 = movh.a sp, #0x4001
|
||||
0x37,0xf0,0x02,0x0e = insert d0, d0, d15, #0x1c, #0x2
|
||||
0xd9,0xff,0xc8,0x22 = lea a15, [a15]#0x2c88
|
||||
0x6d,0xb8,0x80,0x11 = call #-0x8fdd00
|
||||
0x6d,0xb8,0x80,0x11 = call #0x702300
|
||||
0x15,0xd0,0xc0,0xeb = ldlcx #0xd0003f80
|
||||
0x4b,0x00,0x41,0x01 = itof d0, d0
|
||||
0xb4,0xc2 = st.h [a12], d2
|
||||
@ -156,7 +156,7 @@
|
||||
0x60,0xc2 = mov.a a2, d12
|
||||
0xd9,0xff,0x30,0x96 = lea a15, [a15]#0x6270
|
||||
0x37,0xf0,0x02,0xf0 = insert d15, d0, d15, #0, #0x2
|
||||
0x6d,0xa0,0x80,0x11 = call #-0xbfdd00
|
||||
0x6d,0xa0,0x80,0x11 = call #0x402300
|
||||
0x3b,0x00,0x00,0xf3 = mov d15, #0x3000
|
||||
0x6d,0x00,0x26,0x05 = call #0xa4c
|
||||
0xb7,0x0f,0x01,0xf1 = insert d15, d15, #0, #0x2, #0x1
|
||||
@ -559,7 +559,7 @@
|
||||
0x91,0x00,0x00,0xf8 = movh.a a15, #0x8000
|
||||
0x37,0x0f,0x83,0xf1 = insert d15, d15, d0, #0x3, #0x3
|
||||
0x7e,0x05 = jne d15, d0, #0xa
|
||||
0x6d,0xa0,0xf4,0x11 = call #-0xbfdc18
|
||||
0x6d,0xa0,0xf4,0x11 = call #0x4023e8
|
||||
0x49,0xff,0x0c,0x0a = lea a15, [a15]#0xc
|
||||
0xb7,0x6f,0x08,0xf0 = insert d15, d15, #0x6, #0, #0x8
|
||||
0x10,0xe4 = addsc.a a4, a14, d15, #0
|
||||
@ -884,7 +884,7 @@
|
||||
0x6d,0xff,0x78,0xfb = call #-0x910
|
||||
0x3b,0x00,0xd0,0x02 = mov d0, #0x2d00
|
||||
0xd9,0x11,0x00,0x00 = lea a1, [a1]#0
|
||||
0x6d,0x88,0x80,0x11 = call #-0xefdd00
|
||||
0x6d,0x88,0x80,0x11 = call #0x102300
|
||||
0xda,0x05 = mov d15, #0x5
|
||||
0x3c,0x0d = j #0x1a
|
||||
0xe2,0x1f = mul d15, d1
|
||||
|
Loading…
x
Reference in New Issue
Block a user