AS汇编器源码剖析-第2章-Armoprand操作数

来源:互联网 发布:淘宝详情图片尺寸大小 编辑:程序博客网 时间:2024/06/16 02:05

AS汇编器源码剖析-Armoprand操作数

 

aarch64_operands全集定义

操作数oprand在指令手册中都有说明,在代码里全部定义在aarch64_operands[]。

 

const struct aarch64_operandaarch64_operands[] =

{

{AARCH64_OPND_CLASS_NIL, "", 0,{0}, "<none>"},

{AARCH64_OPND_CLASS_INT_REG,"Rd", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_Rd}, "aninteger register"},

{AARCH64_OPND_CLASS_INT_REG,"Rn", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_Rn}, "aninteger register"},

{AARCH64_OPND_CLASS_INT_REG,"Rm", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_Rm}, "aninteger register"},

{AARCH64_OPND_CLASS_INT_REG,"Rt", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_Rt}, "aninteger register"},

{AARCH64_OPND_CLASS_INT_REG,"Rt2", OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_Rt2}, "aninteger register"

…},

 

struct aarch64_operand定义如下:

 

struct aarch64_operand

{

 enum aarch64_operand_class op_class; //操作数的类class

 

 const char *name; //手册里通用的名称

 unsigned int flags;

 

  /*The associated instruction bit-fields; no operand has more than 4

    bit-fields */

 enum aarch64_field_kind fields[4];

 

  /*Brief description */

 const char *desc;

};

 

 

AARCH64_OPND_CLASS_INT_REG

操作数的类class

"Rd"

手册里通用的名称

OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR

操作数flags

{FLD_Rd}

域定义的枚举

"an integer register"

说明

 

 

 

汇编器将arm操作数的情况做了归纳总结,这个和aarch64_operands[]的顺序是一一对应的,也作为aarch64_operands[]的索引使用。

 

/* Operand code that helps both parsing andcoding.

  Keep AARCH64_OPERANDS synced.  */

 

enum aarch64_opnd

{

 AARCH64_OPND_NIL,        /* nooperand---MUST BE FIRST!*/

 

 AARCH64_OPND_Rd, /* Integerregister as destination.  */

 AARCH64_OPND_Rn, /* Integerregister as source.  */

  AARCH64_OPND_Rm,        /* Integer register as source.  */

 AARCH64_OPND_Rt, /* Integerregister used in ld/st instructions.  */

 AARCH64_OPND_Rt2,        /* Integerregister used in ld/st pair instructions. */

 AARCH64_OPND_Rs, /* Integerregister used in ld/st exclusive.  */

 AARCH64_OPND_Ra, /* Integerregister used in ddp_3src instructions. */

 AARCH64_OPND_Rt_SYS,  /* Integerregister used in system instructions.  */

 

 AARCH64_OPND_Rd_SP,   /* Integer Rdor SP.  */

};

 

Rd, Rn, Rm是最为常见的oprand,在代码里的处理会在encoding流程里详细讲解。

 

操作数class定义

 

操作数class定义都在enum aarch64_operand_class,不是很多。

这个是方便归纳处理的,比如AARCH64_OPND_CLASS_INT_REG,实际上Rd,Rn,Rm等操作数,在填充到指令encoding的方式是类似的。

 

enum aarch64_operand_class

{

 AARCH64_OPND_CLASS_NIL,

 AARCH64_OPND_CLASS_INT_REG,

 AARCH64_OPND_CLASS_MODIFIED_REG,

 AARCH64_OPND_CLASS_FP_REG,

 AARCH64_OPND_CLASS_SIMD_REG,

 AARCH64_OPND_CLASS_SIMD_ELEMENT,

 AARCH64_OPND_CLASS_SISD_REG,

 AARCH64_OPND_CLASS_SIMD_REGLIST,

 AARCH64_OPND_CLASS_CP_REG,

 AARCH64_OPND_CLASS_ADDRESS,

 AARCH64_OPND_CLASS_IMMEDIATE,

 AARCH64_OPND_CLASS_SYSTEM,

 AARCH64_OPND_CLASS_COND,

};

 

 

 

操作数flags定义

一共5种定义如下:

/* Operand flags.  */

 

#define OPD_F_HAS_INSERTER     0x00000001

#define OPD_F_HAS_EXTRACTOR 0x00000002

#define OPD_F_SEXT               0x00000004    /*Require sign-extension.  */

#define OPD_F_SHIFT_BY_2  0x00000008    /*Need to left shift the field

                                                       value by 2 to get the value

                                                        of an immediate operand.  */

#define OPD_F_MAYBE_SP             0x00000010    /* May potentially be SP. */

 

 

OPD_F_HAS_INSERTER:需要在encoding的时候插入oprand的bit。在aarch64_operands里定义的绝大多数oprand都配置了这个flag,说明是需要在指令encoding里占用bit的。

 

OPD_F_HAS_EXTRACTOR:在aarch64_operands里和OPD_F_HAS_INSERTER成对出现的。在decode里才会用到,也就是说,AS汇编器不会使用这个。

 

OPD_F_SEXT:指令需要有符号位扩展,可以以ADDR_ADRP为例子看看。

 {AARCH64_OPND_CLASS_ADDRESS, "ADDR_ADRP", OPD_F_SEXT |OPD_F_HAS_EXTRACTOR, {FLD_immhi, FLD_immlo}, "21-bit PC-relative addressof a 4KB page"},

 

OPD_F_MAYBE_SP:可能是stackpointer的寄存器,例子如下:

 {AARCH64_OPND_CLASS_INT_REG, "Rd_SP", OPD_F_MAYBE_SP |OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_Rd}, "an integer or stackpointer register"},

 {AARCH64_OPND_CLASS_INT_REG, "Rn_SP", OPD_F_MAYBE_SP |OPD_F_HAS_INSERTER | OPD_F_HAS_EXTRACTOR, {FLD_Rn}, "an integer or stackpointer register"},

 

操作码位域定义

操作数oprand在指令手册中都有定义好的bit,统一在aarch64_field fields[]数组里定义。

 

域的枚举,用来做field定义的索引。

enum aarch64_field_kind

{

 FLD_NIL,

 FLD_cond2,

 FLD_nzcv,

 FLD_defgh,

 FLD_abc,

 FLD_imm19,

 FLD_immhi,

 FLD_immlo,

 FLD_size,

 FLD_vldst_size,

 FLD_op,

 FLD_Q,

 FLD_Rt,

 FLD_Rd,

 FLD_Rn,

 FLD_Rt2,

 FLD_Ra,

 FLD_op2,

 FLD_CRm,

 FLD_CRn,

 FLD_op1,

 FLD_op0,

 FLD_imm3,

 FLD_cond,

 FLD_opcode,

 FLD_cmode,

 FLD_asisdlso_opcode,

 FLD_len,

 FLD_Rm,

 FLD_Rs,

 FLD_option,

 FLD_S,

 FLD_hw,

 FLD_opc,

 FLD_opc1,

 FLD_shift,

 FLD_type,

 FLD_ldst_size,

 FLD_imm6,

 FLD_imm4,

 FLD_imm5,

 FLD_imm7,

 FLD_imm8,

 FLD_imm9,

 FLD_imm12,

 FLD_imm14,

 FLD_imm16,

 FLD_imm26,

 FLD_imms,

 FLD_immr,

 FLD_immb,

 FLD_immh,

 FLD_N,

 FLD_index,

 FLD_index2,

 FLD_sf,

 FLD_lse_sz,

 FLD_H,

 FLD_L,

 FLD_M,

 FLD_b5,

 FLD_b40,

 FLD_scale,

};

 

 

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 theAdvSIMD 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 and logical 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. */

    {30,  1 },       /*lse_size: in LSE extension atomic 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.  */

};

 

 

0 0
原创粉丝点击