|
@@ -35,6 +35,7 @@
|
|
|
|
|
|
#define AARCH64_INSN_SF_BIT BIT(31)
|
|
|
#define AARCH64_INSN_N_BIT BIT(22)
|
|
|
+#define AARCH64_INSN_LSL_12 BIT(22)
|
|
|
|
|
|
static int aarch64_insn_encoding_class[] = {
|
|
|
AARCH64_INSN_CLS_UNKNOWN,
|
|
@@ -903,9 +904,18 @@ u32 aarch64_insn_gen_add_sub_imm(enum aarch64_insn_register dst,
|
|
|
return AARCH64_BREAK_FAULT;
|
|
|
}
|
|
|
|
|
|
+ /* We can't encode more than a 24bit value (12bit + 12bit shift) */
|
|
|
+ if (imm & ~(BIT(24) - 1))
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ /* If we have something in the top 12 bits... */
|
|
|
if (imm & ~(SZ_4K - 1)) {
|
|
|
- pr_err("%s: invalid immediate encoding %d\n", __func__, imm);
|
|
|
- return AARCH64_BREAK_FAULT;
|
|
|
+ /* ... and in the low 12 bits -> error */
|
|
|
+ if (imm & (SZ_4K - 1))
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ imm >>= 12;
|
|
|
+ insn |= AARCH64_INSN_LSL_12;
|
|
|
}
|
|
|
|
|
|
insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
|
|
@@ -913,6 +923,10 @@ u32 aarch64_insn_gen_add_sub_imm(enum aarch64_insn_register dst,
|
|
|
insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
|
|
|
|
|
|
return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_12, insn, imm);
|
|
|
+
|
|
|
+out:
|
|
|
+ pr_err("%s: invalid immediate encoding %d\n", __func__, imm);
|
|
|
+ return AARCH64_BREAK_FAULT;
|
|
|
}
|
|
|
|
|
|
u32 aarch64_insn_gen_bitfield(enum aarch64_insn_register dst,
|