Skip to content

Commit 5fdc639

Browse files
zlimwildea01
authored andcommitted
arm64: introduce aarch64_insn_gen_add_sub_shifted_reg()
Introduce function to generate add/subtract (shifted register) instructions. Signed-off-by: Zi Shen Lim <zlim.lnx@gmail.com> Acked-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
1 parent 6098f2d commit 5fdc639

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

arch/arm64/include/asm/insn.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ enum aarch64_insn_imm_type {
6767
AARCH64_INSN_IMM_12,
6868
AARCH64_INSN_IMM_9,
6969
AARCH64_INSN_IMM_7,
70+
AARCH64_INSN_IMM_6,
7071
AARCH64_INSN_IMM_S,
7172
AARCH64_INSN_IMM_R,
7273
AARCH64_INSN_IMM_MAX
@@ -206,6 +207,10 @@ __AARCH64_INSN_FUNCS(bfm, 0x7F800000, 0x33000000)
206207
__AARCH64_INSN_FUNCS(movz, 0x7F800000, 0x52800000)
207208
__AARCH64_INSN_FUNCS(ubfm, 0x7F800000, 0x53000000)
208209
__AARCH64_INSN_FUNCS(movk, 0x7F800000, 0x72800000)
210+
__AARCH64_INSN_FUNCS(add, 0x7F200000, 0x0B000000)
211+
__AARCH64_INSN_FUNCS(adds, 0x7F200000, 0x2B000000)
212+
__AARCH64_INSN_FUNCS(sub, 0x7F200000, 0x4B000000)
213+
__AARCH64_INSN_FUNCS(subs, 0x7F200000, 0x6B000000)
209214
__AARCH64_INSN_FUNCS(b, 0xFC000000, 0x14000000)
210215
__AARCH64_INSN_FUNCS(bl, 0xFC000000, 0x94000000)
211216
__AARCH64_INSN_FUNCS(cbz, 0xFE000000, 0x34000000)
@@ -265,6 +270,12 @@ u32 aarch64_insn_gen_movewide(enum aarch64_insn_register dst,
265270
int imm, int shift,
266271
enum aarch64_insn_variant variant,
267272
enum aarch64_insn_movewide_type type);
273+
u32 aarch64_insn_gen_add_sub_shifted_reg(enum aarch64_insn_register dst,
274+
enum aarch64_insn_register src,
275+
enum aarch64_insn_register reg,
276+
int shift,
277+
enum aarch64_insn_variant variant,
278+
enum aarch64_insn_adsb_type type);
268279

269280
bool aarch64_insn_hotpatch_safe(u32 old_insn, u32 new_insn);
270281

arch/arm64/kernel/insn.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ u32 __kprobes aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type,
260260
mask = BIT(7) - 1;
261261
shift = 15;
262262
break;
263+
case AARCH64_INSN_IMM_6:
263264
case AARCH64_INSN_IMM_S:
264265
mask = BIT(6) - 1;
265266
shift = 10;
@@ -698,3 +699,51 @@ u32 aarch64_insn_gen_movewide(enum aarch64_insn_register dst,
698699

699700
return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_16, insn, imm);
700701
}
702+
703+
u32 aarch64_insn_gen_add_sub_shifted_reg(enum aarch64_insn_register dst,
704+
enum aarch64_insn_register src,
705+
enum aarch64_insn_register reg,
706+
int shift,
707+
enum aarch64_insn_variant variant,
708+
enum aarch64_insn_adsb_type type)
709+
{
710+
u32 insn;
711+
712+
switch (type) {
713+
case AARCH64_INSN_ADSB_ADD:
714+
insn = aarch64_insn_get_add_value();
715+
break;
716+
case AARCH64_INSN_ADSB_SUB:
717+
insn = aarch64_insn_get_sub_value();
718+
break;
719+
case AARCH64_INSN_ADSB_ADD_SETFLAGS:
720+
insn = aarch64_insn_get_adds_value();
721+
break;
722+
case AARCH64_INSN_ADSB_SUB_SETFLAGS:
723+
insn = aarch64_insn_get_subs_value();
724+
break;
725+
default:
726+
BUG_ON(1);
727+
}
728+
729+
switch (variant) {
730+
case AARCH64_INSN_VARIANT_32BIT:
731+
BUG_ON(shift & ~(SZ_32 - 1));
732+
break;
733+
case AARCH64_INSN_VARIANT_64BIT:
734+
insn |= AARCH64_INSN_SF_BIT;
735+
BUG_ON(shift & ~(SZ_64 - 1));
736+
break;
737+
default:
738+
BUG_ON(1);
739+
}
740+
741+
742+
insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
743+
744+
insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
745+
746+
insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, reg);
747+
748+
return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_6, insn, shift);
749+
}

0 commit comments

Comments
 (0)