1. 程式人生 > >從編譯器源代碼中提取ARMv8的指令編碼

從編譯器源代碼中提取ARMv8的指令編碼

med constant ray 結構 any exce clas 標識 變量

2012年11月份的資料,之前ARMv8手冊還沒公布,我想辦法從編譯器的binutils中提取出了全部ARMv8指令的二進制編碼,之前不能隨便發,如今相當於解禁了^_^。


問題1:提取ARMv8的指令編碼

答:ARMv8指令的opcode能夠在支持ARMv8的編譯器binutils中找到,該工具能在網上找到,見參考資料[1],或者在[1]中搜索aarch64_opcode_table。

為了說明指令編碼細節。現將網頁中部分內容摘錄例如以下:

1208 struct aarch64_opcode aarch64_opcode_table[] =

1209

{

1210 /* Add/subtract (with carry). */

1211 {"adc", 0x1a000000, 0x7fe0fc00, addsub_carry, 0, CORE, OP3 (Rd, Rn, Rm), QL_I3SAMER, F_SF},

p=jk/arm64/binutils.git;a=blob;f=opcodes/aarch64-tbl.h;h=d360b1406718257da86050f5b3a760cd02196250;hb=aarch64#l1212">1212 {"adcs", 0x3a000000, 0x7fe0fc00, addsub_carry, 0, CORE, OP3 (Rd, Rn, Rm), QL_I3SAMER, F_SF},

以上結構體中的每一項相應某條指令的操作碼等信息。當中aarch64_opcode結構體(見參考文獻[2])在。內容摘錄例如以下:

structaarch64_opcode

{

/*The name of the mnemonic. */

const char *name;

/*The opcode itself. Those bits which willbe filled in with operands are zeroes. */

aarch64_insn opcode;

/*The opcode mask. This is used by thedisassembler. This is a mask containingones indicating those bits which must match the opcode field, and zeroesindicating those bits which need not match (and are presumably filled in byoperands). */

aarch64_insn mask;

/* Instruction class. */

enum aarch64_insn_class iclass;

/*Enumerator identifier. */

enum aarch64_op op;

/*Which architecture variant provides this instruction. */

const aarch64_feature_set *avariant;

/*An array of operand codes. Each code isan index into the operand table. Theyappear in the order which the operands must appear in assembly code, and are terminatedby a zero. */

enum aarch64_opnd operands[AARCH64_MAX_OPND_NUM];

/*A list of operand qualifier code sequence. Each operand qualifier code qualifies the corresponding operandcode. Each operand qualifier sequencespecifies a valid opcode variant and related constraint on operands. */

aarch64_opnd_qualifier_seq_t qualifiers_list[AARCH64_MAX_QLF_SEQ_NUM];

/*Flags providing information about this instruction */

uint32_t flags;

}

依照以上信息解釋aarch64_opcode_table中的結構體例如以下表:

"adc",

0x1a000000

0x7fe0fc00

addsub_carry,

0

CORE

OP3 (Rd, Rn, Rm)

QL_I3SAMER,

F_SF

助記符

操作碼

操作碼掩碼

指令所屬類

枚舉器標識符

提供這樣的指令的結構體變量

操作數編碼數組

操作數限定符的代碼序列列表

指令信息標誌位

1:Aarch64-opc.c中有關於指令位域的定義。

const aarch64_field fields[] =

{

{ 0, 0 }, /*NIL. */

{ 0, 4 }, /*cond2: condition in truly conditional-executed inst. */

{ 0, 4 }, /*nzcv: flag bit specifier, encoded in the "nzcv" field. */

{ 5, 5 }, /*defgh: d:e:f:g:h bits in AdvSIMD modified immediate. */

{16, 3 }, /*abc: a:b:c bits in AdvSIMD modified immediate. */

{ 5, 19 }, /* imm19: e.g. in CBZ. */

{ 5, 19 }, /* immhi: e.g. in ADRP. */

{29, 2 }, /*immlo: e.g. in ADRP. */

{22, 2 }, /*size: in most AdvSIMD and floating-point instructions. */

{10, 2 }, /*vldst_size: size field in the AdvSIMD load/store inst. */

{29, 1 }, /*op: in AdvSIMD modified immediate instructions. */

{30, 1 }, /*Q: in most AdvSIMD instructions. */

{ 0, 5 }, /*Rt: in load/store instructions. */

{ 0, 5 }, /*Rd: in many integer instructions. */

{ 5, 5 }, /*Rn: in many integer instructions. */

{10, 5 }, /*Rt2: in load/store pair instructions. */

{10, 5 }, /*Ra: in fp instructions. */

{ 5, 3 }, /*op2: in the system instructions. */

{ 8, 4 }, /*CRm: in the system instructions. */

{12, 4 }, /*CRn: in the system instructions. */

{16, 3 }, /*op1: in the system instructions. */

{19, 2 }, /*op0: in the system instructions. */

{10, 3 }, /*imm3: in add/sub extended reg instructions. */

{12, 4 }, /*cond: condition flags as a source operand. */

{12, 4 }, /*opcode: in advsimd load/store instructions. */

{12, 4 }, /*cmode: in advsimd modified immediate instructions. */

{13, 3 }, /*asisdlso_opcode: opcode in advsimd ld/st single element. */

{13, 2 }, /*len: in advsimd tbl/tbx instructions. */

{16, 5 }, /*Rm: in ld/st reg offset and some integer inst. */

{16, 5 }, /*Rs: in load/store exclusive instructions. */

{13, 3 }, /*option: in ld/st reg offset + add/sub extended reg inst. */

{12, 1 }, /*S: in load/store reg offset instructions. */

{21, 2 }, /*hw: in move wide constant instructions. */

{22, 2 }, /*opc: in load/store reg offset instructions. */

{23, 1 }, /*opc1: in load/store reg offset instructions. */

{22, 2 }, /*shift: in add/sub reg/imm shifted instructions. */

{22, 2 }, /*type: floating point type field in fp data inst. */

{30, 2 }, /*ldst_size: size field in ld/st reg offset inst. */

{10, 6 }, /*imm6: in add/sub reg shifted instructions. */

{11, 4 }, /*imm4: in advsimd ext and advsimd ins instructions. */

{16, 5 }, /*imm5: in conditional compare (immediate) instructions. */

{15, 7 }, /*imm7: in load/store pair pre/post index instructions. */

{13, 8 }, /*imm8: in floating-point scalar move immediate inst. */

{12, 9 }, /*imm9: in load/store pre/post index instructions. */

{10, 12 }, /* imm12: in ld/stunsigned imm or add/sub shifted inst. */

{ 5, 14 }, /* imm14: in test bit and branch instructions. */

{ 5, 16 }, /* imm16: in exception instructions. */

{ 0, 26 }, /* imm26: in unconditional branch instructions. */

{ 10, 6 }, /* imms: in bitfield andlogical immediate instructions. */

{16, 6 }, /*immr: in bitfield and logical immediate instructions. */

{16, 3 }, /*immb: in advsimd shift by immediate instructions. */

{19, 4 }, /*immh: in advsimd shift by immediate instructions. */

{22, 1 }, /*N: in logical (immediate) instructions. */

{11, 1 }, /*index: in ld/st inst deciding the pre/post-index. */

{24, 1 }, /*index2: in ld/st pair inst deciding the pre/post-index. */

{31, 1 }, /*sf: in integer data processing instructions. */

{11, 1 }, /*H: in advsimd scalar x indexed element instructions. */

{21, 1 }, /*L: in advsimd scalar x indexed element instructions. */

{20, 1 }, /*M: in advsimd scalar x indexed element instructions. */

{31, 1 }, /*b5: in the test bit and branch instructions. */

{19, 5 }, /*b40: in the test bit and branch instructions. */

{10, 6 }, /*scale: in the fixed-point scalar to fp converting inst. */

};

2、函數aarch64_opcode_encode用於將操作數插入opcode中

參考資料

[1] ARMv8的編譯器binutils,結構體aarch64_opcode_table定義見line 1208

p=jk/arm64/binutils.git;a=blob;f=opcodes/aarch64-tbl.h;h=d360b1406718257da86050f5b3a760cd02196250;hb=aarch64">http://kernel.ubuntu.com/git?p=jk/arm64/binutils.git;a=blob;f=opcodes/aarch64-tbl.h;h=d360b1406718257da86050f5b3a760cd02196250;hb=aarch64

[2] 結構體aarch64_opcode定義,line451

http://kernel.ubuntu.com/git?p=jk/arm64/binutils.git;a=blob;f=include/opcode/aarch64.h;h=98529954ea098349eb16572d4915f4edbd2e7b5d;hb=aarch64

[3] 《ARMv8 InstructionSet Overview 》page11

從編譯器源代碼中提取ARMv8的指令編碼