@@ -48,10 +48,12 @@ struct ArgumentDesc {
48
48
/* * Check whether given value fits into this instruction field. */
49
49
[[nodiscard]] constexpr bool is_value_in_field_range (RegisterValue val) const {
50
50
if (min < 0 ) {
51
- return val.as_i64 () <= max && val.as_i64 () >= min;
51
+ int32_t val_ = val.as_i32 ();
52
+ val_ >>= arg.str_shift ;
53
+ return val_ <= max && val_ >= min;
52
54
} else {
53
- return val.as_u64 () <= static_cast < uint64_t >(max)
54
- && val. as_u64 () >= static_cast <uint64_t >(min);
55
+ uint64_t val_ = val.as_u64 () >> arg. str_shift ;
56
+ return val_ <= static_cast < uint64_t >(max) && val_ >= static_cast <uint64_t >(min);
55
57
}
56
58
}
57
59
@@ -70,11 +72,16 @@ static const ArgumentDesc arg_desc_list[] = {
70
72
// Shift for bit shift instructions (5bits)
71
73
ArgumentDesc (' >' , ' n' , 0 , 0x1f , { { { 5 , 20 } }, 0 }),
72
74
// Address offset immediate (20bits), encoded in multiples of 2 bytes
73
- ArgumentDesc (' a' , ' a' , -0x80000 , 0x7ffff , { { { 10 , 21 }, { 1 , 20 }, { 8 , 12 }, { 1 , 31 } }, 1 }),
75
+ ArgumentDesc (
76
+ ' a' ,
77
+ ' a' ,
78
+ -0x80000 ,
79
+ 0x7ffff ,
80
+ { { { 10 , 21 }, { 1 , 20 }, { 8 , 12 }, { 1 , 31 } }, 1 , 0 }),
74
81
// U-type immediate for LUI and AUIPC (20bits)
75
- ArgumentDesc (' u' , ' n' , 0 , 0xfffff000 , { { { 20 , 12 } }, 0 }),
82
+ ArgumentDesc (' u' , ' n' , 0 , 0xfffff , { { { 20 , 12 } }, 0 , 12 }),
76
83
// B-type immediate for branches (12 bits)
77
- ArgumentDesc (' p' , ' p' , -0x1000 , 0x0fff , { { { 4 , 8 }, { 6 , 25 }, { 1 , 7 }, { 1 , 31 } }, 1 }),
84
+ ArgumentDesc (' p' , ' p' , -0x1000 , 0x0fff , { { { 4 , 8 }, { 6 , 25 }, { 1 , 7 }, { 1 , 31 } }, 1 , 0 }),
78
85
// Offset immediate for load instructions (12 bits)
79
86
ArgumentDesc (' o' , ' o' , -0x800 , 0x7ff , { { { 12 , 20 } }, 0 }),
80
87
// Offset immediate for store instructions (12 bits)
@@ -84,7 +91,7 @@ static const ArgumentDesc arg_desc_list[] = {
84
91
ArgumentDesc (' Z' , ' n' , 0 , 0x1f , { { { 5 , 15 } }, 0 }),
85
92
// 12-bit CSR address
86
93
// (https://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=opcodes/riscv-opc.c;h=7e95f645c5c5fe0a7c93c64c2f1719efaec67972;hb=HEAD#l928)
87
- ArgumentDesc (' E' , ' E' , 0 , 0xfff , { { { 12 , 20 } }, 0 }),
94
+ ArgumentDesc (' E' , ' E' , 0 , 0xfff , { { { 12 , 20 } }, 0 , 20 }),
88
95
};
89
96
90
97
static const ArgumentDesc *arg_desc_by_code[(int )(' z' + 1 )];
@@ -786,10 +793,11 @@ QString Instruction::to_str(Address inst_addr) const {
786
793
res += arg_letter;
787
794
continue ;
788
795
}
789
- auto field = (int32_t )arg_desc->arg .decode (this ->dt );
796
+
797
+ auto field = (int32_t )arg_desc->arg .decode_str (this ->dt );
790
798
if (arg_desc->min < 0 ) {
791
799
field = extend (field, [&]() {
792
- int sum = (int )arg_desc->arg .shift ;
800
+ int sum = (int )arg_desc->arg .str_shift ;
793
801
for (auto chunk : arg_desc->arg ) {
794
802
sum += chunk.count ;
795
803
}
@@ -808,6 +816,7 @@ QString Instruction::to_str(Address inst_addr) const {
808
816
case ' p' :
809
817
case ' a' : {
810
818
field += (int32_t )inst_addr.get_raw ();
819
+ QString a = str::asHex (field);
811
820
res.append (str::asHex (field));
812
821
break ;
813
822
}
@@ -1401,7 +1410,7 @@ bool Instruction::update(int64_t val, RelocExpression *relocexp) {
1401
1410
if (relocexp->pseudo_mod != Modifier::NONE) {
1402
1411
val = (int64_t )modify_pseudoinst_imm (relocexp->pseudo_mod , val);
1403
1412
} else {
1404
- if ((val & ((1 << relocexp->arg ->shift ) - 1 ))) { return false ; }
1413
+ if ((val & ((1 << relocexp->arg ->str_shift ) - 1 ))) { return false ; }
1405
1414
if (relocexp->min < 0 ) {
1406
1415
if (((int64_t )val < relocexp->min ) || ((int64_t )val > relocexp->max )) {
1407
1416
if (((int64_t )val - 0x100000000 < relocexp->min )
0 commit comments