instructions written (aka. 1). */
int
-emit_insn (uint32_t *buf, uint32_t insn)
+aarch64_emit_insn (uint32_t *buf, uint32_t insn)
{
*buf = insn;
return 1;
{
op = ENCODE (1, 1, 24);
- return emit_insn (buf, opcode | ENCODE (size, 2, 30) | op
- | ENCODE (operand.index >> 3, 12, 10)
- | ENCODE (rn.num, 5, 5)
- | ENCODE (rt.num, 5, 0));
+ return aarch64_emit_insn (buf, opcode | ENCODE (size, 2, 30) | op
+ | ENCODE (operand.index >> 3, 12, 10)
+ | ENCODE (rn.num, 5, 5)
+ | ENCODE (rt.num, 5, 0));
}
case MEMORY_OPERAND_POSTINDEX:
{
op = ENCODE (0, 1, 24);
- return emit_insn (buf, opcode | ENCODE (size, 2, 30) | op
- | post_index | ENCODE (operand.index, 9, 12)
- | ENCODE (rn.num, 5, 5) | ENCODE (rt.num, 5, 0));
+ return aarch64_emit_insn (buf, opcode | ENCODE (size, 2, 30) | op
+ | post_index | ENCODE (operand.index, 9, 12)
+ | ENCODE (rn.num, 5, 5)
+ | ENCODE (rt.num, 5, 0));
}
case MEMORY_OPERAND_PREINDEX:
{
op = ENCODE (0, 1, 24);
- return emit_insn (buf, opcode | ENCODE (size, 2, 30) | op
- | pre_index | ENCODE (operand.index, 9, 12)
- | ENCODE (rn.num, 5, 5)
- | ENCODE (rt.num, 5, 0));
+ return aarch64_emit_insn (buf, opcode | ENCODE (size, 2, 30) | op
+ | pre_index | ENCODE (operand.index, 9, 12)
+ | ENCODE (rn.num, 5, 5)
+ | ENCODE (rt.num, 5, 0));
}
default:
return 0;
+/- 128MB (26 bits << 2). */
#define emit_b(buf, is_bl, offset) \
- emit_insn (buf, ((is_bl) ? BL : B) | (ENCODE ((offset) >> 2, 26, 0)))
+ aarch64_emit_insn (buf, ((is_bl) ? BL : B) | (ENCODE ((offset) >> 2, 26, 0)))
/* Write a BCOND instruction into *BUF.
byte-addressed but should be 4 bytes aligned. It has a limited range of
+/- 1MB (19 bits << 2). */
-#define emit_bcond(buf, cond, offset) \
- emit_insn (buf, \
- BCOND | ENCODE ((offset) >> 2, 19, 5) \
- | ENCODE ((cond), 4, 0))
+#define emit_bcond(buf, cond, offset) \
+ aarch64_emit_insn (buf, \
+ BCOND | ENCODE ((offset) >> 2, 19, 5) \
+ | ENCODE ((cond), 4, 0))
/* Write a CBZ or CBNZ instruction into *BUF.
byte-addressed but should be 4 bytes aligned. It has a limited range of
+/- 1MB (19 bits << 2). */
-#define emit_cb(buf, is_cbnz, rt, offset) \
- emit_insn (buf, \
- ((is_cbnz) ? CBNZ : CBZ) \
- | ENCODE (rt.is64, 1, 31) /* sf */ \
- | ENCODE (offset >> 2, 19, 5) /* imm19 */ \
- | ENCODE (rt.num, 5, 0))
+#define emit_cb(buf, is_cbnz, rt, offset) \
+ aarch64_emit_insn (buf, \
+ ((is_cbnz) ? CBNZ : CBZ) \
+ | ENCODE (rt.is64, 1, 31) /* sf */ \
+ | ENCODE (offset >> 2, 19, 5) /* imm19 */ \
+ | ENCODE (rt.num, 5, 0))
/* Write a LDR instruction into *BUF.
byte-addressed but should be 4 bytes aligned. It has a limited range of
+/- 32KB (14 bits << 2). */
-#define emit_tb(buf, is_tbnz, bit, rt, offset) \
- emit_insn (buf, \
- ((is_tbnz) ? TBNZ: TBZ) \
- | ENCODE (bit >> 5, 1, 31) /* b5 */ \
- | ENCODE (bit, 5, 19) /* b40 */ \
- | ENCODE (offset >> 2, 14, 5) /* imm14 */ \
- | ENCODE (rt.num, 5, 0))
+#define emit_tb(buf, is_tbnz, bit, rt, offset) \
+ aarch64_emit_insn (buf, \
+ ((is_tbnz) ? TBNZ: TBZ) \
+ | ENCODE (bit >> 5, 1, 31) /* b5 */ \
+ | ENCODE (bit, 5, 19) /* b40 */ \
+ | ENCODE (offset >> 2, 14, 5) /* imm14 */ \
+ | ENCODE (rt.num, 5, 0))
/* Write a NOP instruction into *BUF. */
-#define emit_nop(buf) emit_insn (buf, NOP)
+#define emit_nop(buf) aarch64_emit_insn (buf, NOP)
-int emit_insn (uint32_t *buf, uint32_t insn);
+int aarch64_emit_insn (uint32_t *buf, uint32_t insn);
int emit_load_store (uint32_t *buf, uint32_t size,
enum aarch64_opcodes opcode,
static int
emit_blr (uint32_t *buf, struct aarch64_register rn)
{
- return emit_insn (buf, BLR | ENCODE (rn.num, 5, 5));
+ return aarch64_emit_insn (buf, BLR | ENCODE (rn.num, 5, 5));
}
/* Write a RET instruction into *BUF.
static int
emit_ret (uint32_t *buf, struct aarch64_register rn)
{
- return emit_insn (buf, RET | ENCODE (rn.num, 5, 5));
+ return aarch64_emit_insn (buf, RET | ENCODE (rn.num, 5, 5));
}
static int
return 0;
}
- return emit_insn (buf, opcode | opc | pre_index | write_back
- | ENCODE (operand.index >> 3, 7, 15)
- | ENCODE (rt2.num, 5, 10)
- | ENCODE (rn.num, 5, 5) | ENCODE (rt.num, 5, 0));
+ return aarch64_emit_insn (buf, opcode | opc | pre_index | write_back
+ | ENCODE (operand.index >> 3, 7, 15)
+ | ENCODE (rt2.num, 5, 10)
+ | ENCODE (rn.num, 5, 5) | ENCODE (rt.num, 5, 0));
}
/* Write a STP instruction into *BUF.
uint32_t opc = ENCODE (2, 2, 30);
uint32_t pre_index = ENCODE (1, 1, 24);
- return emit_insn (buf, LDP_SIMD_VFP | opc | pre_index
- | ENCODE (offset >> 4, 7, 15) | ENCODE (rt2, 5, 10)
- | ENCODE (rn.num, 5, 5) | ENCODE (rt, 5, 0));
+ return aarch64_emit_insn (buf, LDP_SIMD_VFP | opc | pre_index
+ | ENCODE (offset >> 4, 7, 15)
+ | ENCODE (rt2, 5, 10)
+ | ENCODE (rn.num, 5, 5) | ENCODE (rt, 5, 0));
}
/* Write a STP (SIMD&VFP) instruction using Q registers into *BUF.
uint32_t opc = ENCODE (2, 2, 30);
uint32_t pre_index = ENCODE (1, 1, 24);
- return emit_insn (buf, STP_SIMD_VFP | opc | pre_index
+ return aarch64_emit_insn (buf, STP_SIMD_VFP | opc | pre_index
| ENCODE (offset >> 4, 7, 15)
| ENCODE (rt2, 5, 10)
| ENCODE (rn.num, 5, 5) | ENCODE (rt, 5, 0));
struct aarch64_register rt2,
struct aarch64_register rn)
{
- return emit_insn (buf, opcode | ENCODE (size, 2, 30)
- | ENCODE (rs.num, 5, 16) | ENCODE (rt2.num, 5, 10)
- | ENCODE (rn.num, 5, 5) | ENCODE (rt.num, 5, 0));
+ return aarch64_emit_insn (buf, opcode | ENCODE (size, 2, 30)
+ | ENCODE (rs.num, 5, 16) | ENCODE (rt2.num, 5, 10)
+ | ENCODE (rn.num, 5, 5) | ENCODE (rt.num, 5, 0));
}
/* Write a LAXR instruction into *BUF.
{
uint32_t size = ENCODE (rd.is64, 1, 31);
- return emit_insn (buf, opcode | size | ENCODE (rm.num, 5, 16)
- | ENCODE (rn.num, 5, 5) | ENCODE (rd.num, 5, 0));
+ return aarch64_emit_insn (buf, opcode | size | ENCODE (rm.num, 5, 16)
+ | ENCODE (rn.num, 5, 5) | ENCODE (rd.num, 5, 0));
}
/* Helper function for data processing instructions taking either a register
/* xxx1 000x xxxx xxxx xxxx xxxx xxxx xxxx */
operand_opcode = ENCODE (8, 4, 25);
- return emit_insn (buf, opcode | operand_opcode | size
- | ENCODE (operand.imm, 12, 10)
- | ENCODE (rn.num, 5, 5) | ENCODE (rd.num, 5, 0));
+ return aarch64_emit_insn (buf, opcode | operand_opcode | size
+ | ENCODE (operand.imm, 12, 10)
+ | ENCODE (rn.num, 5, 5)
+ | ENCODE (rd.num, 5, 0));
}
else
{
/* Do not shift the immediate. */
uint32_t shift = ENCODE (0, 2, 21);
- return emit_insn (buf, MOV | size | shift
- | ENCODE (operand.imm, 16, 5)
- | ENCODE (rd.num, 5, 0));
+ return aarch64_emit_insn (buf, MOV | size | shift
+ | ENCODE (operand.imm, 16, 5)
+ | ENCODE (rd.num, 5, 0));
}
else
return emit_add (buf, rd, operand.reg, immediate_operand (0));
{
uint32_t size = ENCODE (rd.is64, 1, 31);
- return emit_insn (buf, MOVK | size | ENCODE (shift, 2, 21) |
- ENCODE (imm, 16, 5) | ENCODE (rd.num, 5, 0));
+ return aarch64_emit_insn (buf, MOVK | size | ENCODE (shift, 2, 21) |
+ ENCODE (imm, 16, 5) | ENCODE (rd.num, 5, 0));
}
/* Write instructions into *BUF in order to move ADDR into a register.
emit_mrs (uint32_t *buf, struct aarch64_register rt,
enum aarch64_system_control_registers system_reg)
{
- return emit_insn (buf, MRS | ENCODE (system_reg, 15, 5)
- | ENCODE (rt.num, 5, 0));
+ return aarch64_emit_insn (buf, MRS | ENCODE (system_reg, 15, 5)
+ | ENCODE (rt.num, 5, 0));
}
/* Write a MSR instruction into *BUF. The register size is 64-bit.
emit_msr (uint32_t *buf, enum aarch64_system_control_registers system_reg,
struct aarch64_register rt)
{
- return emit_insn (buf, MSR | ENCODE (system_reg, 15, 5)
- | ENCODE (rt.num, 5, 0));
+ return aarch64_emit_insn (buf, MSR | ENCODE (system_reg, 15, 5)
+ | ENCODE (rt.num, 5, 0));
}
/* Write a SEVL instruction into *BUF.
static int
emit_sevl (uint32_t *buf)
{
- return emit_insn (buf, SEVL);
+ return aarch64_emit_insn (buf, SEVL);
}
/* Write a WFE instruction into *BUF.
static int
emit_wfe (uint32_t *buf)
{
- return emit_insn (buf, WFE);
+ return aarch64_emit_insn (buf, WFE);
}
/* Write a SBFM instruction into *BUF.
uint32_t size = ENCODE (rd.is64, 1, 31);
uint32_t n = ENCODE (rd.is64, 1, 22);
- return emit_insn (buf, SBFM | size | n | ENCODE (immr, 6, 16)
- | ENCODE (imms, 6, 10) | ENCODE (rn.num, 5, 5)
- | ENCODE (rd.num, 5, 0));
+ return aarch64_emit_insn (buf, SBFM | size | n | ENCODE (immr, 6, 16)
+ | ENCODE (imms, 6, 10) | ENCODE (rn.num, 5, 5)
+ | ENCODE (rd.num, 5, 0));
}
/* Write a SBFX instruction into *BUF.
uint32_t size = ENCODE (rd.is64, 1, 31);
uint32_t n = ENCODE (rd.is64, 1, 22);
- return emit_insn (buf, UBFM | size | n | ENCODE (immr, 6, 16)
- | ENCODE (imms, 6, 10) | ENCODE (rn.num, 5, 5)
- | ENCODE (rd.num, 5, 0));
+ return aarch64_emit_insn (buf, UBFM | size | n | ENCODE (immr, 6, 16)
+ | ENCODE (imms, 6, 10) | ENCODE (rn.num, 5, 5)
+ | ENCODE (rd.num, 5, 0));
}
/* Write a UBFX instruction into *BUF.
{
uint32_t size = ENCODE (rd.is64, 1, 31);
- return emit_insn (buf, CSINC | size | ENCODE (rm.num, 5, 16)
- | ENCODE (cond, 4, 12) | ENCODE (rn.num, 5, 5)
- | ENCODE (rd.num, 5, 0));
+ return aarch64_emit_insn (buf, CSINC | size | ENCODE (rm.num, 5, 16)
+ | ENCODE (cond, 4, 12) | ENCODE (rn.num, 5, 5)
+ | ENCODE (rd.num, 5, 0));
}
/* Write a CSET instruction into *BUF.
/* The instruction is not PC relative. Just re-emit it at the new
location. */
- insn_reloc->insn_ptr += emit_insn (insn_reloc->insn_ptr, insn);
+ insn_reloc->insn_ptr += aarch64_emit_insn (insn_reloc->insn_ptr, insn);
}
static const struct aarch64_insn_visitor visitor =