Skip to content

Commit

Permalink
arm64: insn: Allow ADD/SUB (immediate) with LSL FireflyTeam#12
Browse files Browse the repository at this point in the history
The encoder for ADD/SUB (immediate) can only cope with 12bit
immediates, while there is an encoding for a 12bit immediate shifted
by 12 bits to the left.

Let's fix this small oversight by allowing the LSL_12 bit to be set.

Reviewed-by: Christoffer Dall <[email protected]>
Acked-by: Catalin Marinas <[email protected]>
Signed-off-by: Marc Zyngier <[email protected]>
  • Loading branch information
Marc Zyngier committed Mar 19, 2018
1 parent 9f2efa3 commit 11d7640
Showing 1 changed file with 16 additions and 2 deletions.
18 changes: 16 additions & 2 deletions arch/arm64/kernel/insn.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -903,16 +904,29 @@ 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);

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,
Expand Down

0 comments on commit 11d7640

Please sign in to comment.