x86: drop seg_entry
Use struct reg_entry instead for most purposes, with a separate array holding just the respective opcode prefix bytes.
This commit is contained in:
parent
3468486226
commit
5e0423804a
@ -1,3 +1,18 @@
|
|||||||
|
2021-03-30 Jan Beulich <jbeulich@suse.com>
|
||||||
|
|
||||||
|
* config/tc-i386.c (build_modrm_byte): Change return type.
|
||||||
|
Change type of "default_seg". Use NULL. Adjust setting of
|
||||||
|
"default_seg".
|
||||||
|
(reg_ds, reg_es, reg_ss): New.
|
||||||
|
(struct _i386_insn): Change type of seg[].
|
||||||
|
(md_begin): Initialize reg_ds, reg_es, and reg_ss.
|
||||||
|
(swap_operands): Change type of "temp_seg".
|
||||||
|
(check_string): Adjust %es check.
|
||||||
|
(process_operands): Change type of "default_seg". Use NULL.
|
||||||
|
Adjust segment override processing..
|
||||||
|
(i386_att_operand): Adjust segment override handling.
|
||||||
|
* config/tc-i386-intel.c (i386_intel_operand): Likewise.
|
||||||
|
|
||||||
2021-03-30 Jan Beulich <jbeulich@suse.com>
|
2021-03-30 Jan Beulich <jbeulich@suse.com>
|
||||||
|
|
||||||
* config/tc-i386.c (reg_eax): New.
|
* config/tc-i386.c (reg_eax): New.
|
||||||
|
@ -1028,16 +1028,10 @@ i386_intel_operand (char *operand_string, int got_a_float)
|
|||||||
as_warn (_("redundant segment overrides"));
|
as_warn (_("redundant segment overrides"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch (i386_regtab[expP->X_add_number].reg_num)
|
if (i386_regtab[expP->X_add_number].reg_num == RegFlat)
|
||||||
{
|
i.seg[i.mem_operands] = NULL;
|
||||||
case 0: i.seg[i.mem_operands] = &es; break;
|
else
|
||||||
case 1: i.seg[i.mem_operands] = &cs; break;
|
i.seg[i.mem_operands] = &i386_regtab[expP->X_add_number];
|
||||||
case 2: i.seg[i.mem_operands] = &ss; break;
|
|
||||||
case 3: i.seg[i.mem_operands] = &ds; break;
|
|
||||||
case 4: i.seg[i.mem_operands] = &fs; break;
|
|
||||||
case 5: i.seg[i.mem_operands] = &gs; break;
|
|
||||||
case RegFlat: i.seg[i.mem_operands] = NULL; break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!i386_index_check (operand_string))
|
if (!i386_index_check (operand_string))
|
||||||
|
@ -190,7 +190,7 @@ static int check_qword_reg (void);
|
|||||||
static int check_word_reg (void);
|
static int check_word_reg (void);
|
||||||
static int finalize_imm (void);
|
static int finalize_imm (void);
|
||||||
static int process_operands (void);
|
static int process_operands (void);
|
||||||
static const seg_entry *build_modrm_byte (void);
|
static const reg_entry *build_modrm_byte (void);
|
||||||
static void output_insn (void);
|
static void output_insn (void);
|
||||||
static void output_imm (fragS *, offsetT);
|
static void output_imm (fragS *, offsetT);
|
||||||
static void output_disp (fragS *, offsetT);
|
static void output_disp (fragS *, offsetT);
|
||||||
@ -215,6 +215,9 @@ static const reg_entry bad_reg = { "<bad>", OPERAND_TYPE_NONE, 0, 0,
|
|||||||
{ Dw2Inval, Dw2Inval } };
|
{ Dw2Inval, Dw2Inval } };
|
||||||
|
|
||||||
static const reg_entry *reg_eax;
|
static const reg_entry *reg_eax;
|
||||||
|
static const reg_entry *reg_ds;
|
||||||
|
static const reg_entry *reg_es;
|
||||||
|
static const reg_entry *reg_ss;
|
||||||
static const reg_entry *reg_st0;
|
static const reg_entry *reg_st0;
|
||||||
static const reg_entry *reg_k0;
|
static const reg_entry *reg_k0;
|
||||||
|
|
||||||
@ -308,7 +311,7 @@ struct _i386_insn
|
|||||||
|
|
||||||
/* SEG gives the seg_entries of this insn. They are zero unless
|
/* SEG gives the seg_entries of this insn. They are zero unless
|
||||||
explicit segment overrides are given. */
|
explicit segment overrides are given. */
|
||||||
const seg_entry *seg[2];
|
const reg_entry *seg[2];
|
||||||
|
|
||||||
/* Copied first memory operand string, for re-checking. */
|
/* Copied first memory operand string, for re-checking. */
|
||||||
char *memop1_string;
|
char *memop1_string;
|
||||||
@ -3107,6 +3110,15 @@ md_begin (void)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SReg:
|
||||||
|
switch (regtab->reg_num)
|
||||||
|
{
|
||||||
|
case 0: reg_es = regtab; break;
|
||||||
|
case 2: reg_ss = regtab; break;
|
||||||
|
case 3: reg_ds = regtab; break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case RegMask:
|
case RegMask:
|
||||||
if (!regtab->reg_num)
|
if (!regtab->reg_num)
|
||||||
reg_k0 = regtab;
|
reg_k0 = regtab;
|
||||||
@ -5522,7 +5534,7 @@ swap_operands (void)
|
|||||||
|
|
||||||
if (i.mem_operands == 2)
|
if (i.mem_operands == 2)
|
||||||
{
|
{
|
||||||
const seg_entry *temp_seg;
|
const reg_entry *temp_seg;
|
||||||
temp_seg = i.seg[0];
|
temp_seg = i.seg[0];
|
||||||
i.seg[0] = i.seg[1];
|
i.seg[0] = i.seg[1];
|
||||||
i.seg[1] = temp_seg;
|
i.seg[1] = temp_seg;
|
||||||
@ -6752,7 +6764,7 @@ check_string (void)
|
|||||||
unsigned int es_op = i.tm.opcode_modifier.isstring - IS_STRING_ES_OP0;
|
unsigned int es_op = i.tm.opcode_modifier.isstring - IS_STRING_ES_OP0;
|
||||||
unsigned int op = i.tm.operand_types[0].bitfield.baseindex ? es_op : 0;
|
unsigned int op = i.tm.operand_types[0].bitfield.baseindex ? es_op : 0;
|
||||||
|
|
||||||
if (i.seg[op] != NULL && i.seg[op] != &es)
|
if (i.seg[op] != NULL && i.seg[op] != reg_es)
|
||||||
{
|
{
|
||||||
as_bad (_("`%s' operand %u must use `%ses' segment"),
|
as_bad (_("`%s' operand %u must use `%ses' segment"),
|
||||||
i.tm.name,
|
i.tm.name,
|
||||||
@ -7543,7 +7555,7 @@ process_operands (void)
|
|||||||
/* Default segment register this instruction will use for memory
|
/* Default segment register this instruction will use for memory
|
||||||
accesses. 0 means unknown. This is only for optimizing out
|
accesses. 0 means unknown. This is only for optimizing out
|
||||||
unnecessary segment overrides. */
|
unnecessary segment overrides. */
|
||||||
const seg_entry *default_seg = 0;
|
const reg_entry *default_seg = NULL;
|
||||||
|
|
||||||
if (i.tm.opcode_modifier.sse2avx)
|
if (i.tm.opcode_modifier.sse2avx)
|
||||||
{
|
{
|
||||||
@ -7730,13 +7742,13 @@ process_operands (void)
|
|||||||
else if (i.tm.opcode_modifier.opcodespace == SPACE_BASE
|
else if (i.tm.opcode_modifier.opcodespace == SPACE_BASE
|
||||||
&& (i.tm.base_opcode & ~3) == MOV_AX_DISP32)
|
&& (i.tm.base_opcode & ~3) == MOV_AX_DISP32)
|
||||||
{
|
{
|
||||||
default_seg = &ds;
|
default_seg = reg_ds;
|
||||||
}
|
}
|
||||||
else if (i.tm.opcode_modifier.isstring)
|
else if (i.tm.opcode_modifier.isstring)
|
||||||
{
|
{
|
||||||
/* For the string instructions that allow a segment override
|
/* For the string instructions that allow a segment override
|
||||||
on one of their operands, the default segment is ds. */
|
on one of their operands, the default segment is ds. */
|
||||||
default_seg = &ds;
|
default_seg = reg_ds;
|
||||||
}
|
}
|
||||||
else if (i.short_form)
|
else if (i.short_form)
|
||||||
{
|
{
|
||||||
@ -7789,9 +7801,9 @@ process_operands (void)
|
|||||||
point, and the specified segment prefix will always be used. */
|
point, and the specified segment prefix will always be used. */
|
||||||
if (i.seg[0]
|
if (i.seg[0]
|
||||||
&& i.seg[0] != default_seg
|
&& i.seg[0] != default_seg
|
||||||
&& i.seg[0]->seg_prefix != i.prefix[SEG_PREFIX])
|
&& i386_seg_prefixes[i.seg[0]->reg_num] != i.prefix[SEG_PREFIX])
|
||||||
{
|
{
|
||||||
if (!add_prefix (i.seg[0]->seg_prefix))
|
if (!add_prefix (i386_seg_prefixes[i.seg[0]->reg_num]))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@ -7816,10 +7828,10 @@ static INLINE void set_rex_vrex (const reg_entry *r, unsigned int rex_bit,
|
|||||||
i.vrex |= rex_bit;
|
i.vrex |= rex_bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const seg_entry *
|
static const reg_entry *
|
||||||
build_modrm_byte (void)
|
build_modrm_byte (void)
|
||||||
{
|
{
|
||||||
const seg_entry *default_seg = 0;
|
const reg_entry *default_seg = NULL;
|
||||||
unsigned int source, dest;
|
unsigned int source, dest;
|
||||||
int vex_3_sources;
|
int vex_3_sources;
|
||||||
|
|
||||||
@ -8103,7 +8115,7 @@ build_modrm_byte (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
default_seg = &ds;
|
default_seg = reg_ds;
|
||||||
|
|
||||||
if (i.base_reg == 0)
|
if (i.base_reg == 0)
|
||||||
{
|
{
|
||||||
@ -8197,7 +8209,7 @@ build_modrm_byte (void)
|
|||||||
i.rm.regmem = i.index_reg->reg_num - 6;
|
i.rm.regmem = i.index_reg->reg_num - 6;
|
||||||
break;
|
break;
|
||||||
case 5: /* (%bp) */
|
case 5: /* (%bp) */
|
||||||
default_seg = &ss;
|
default_seg = reg_ss;
|
||||||
if (i.index_reg == 0)
|
if (i.index_reg == 0)
|
||||||
{
|
{
|
||||||
i.rm.regmem = 6;
|
i.rm.regmem = 6;
|
||||||
@ -8258,7 +8270,7 @@ build_modrm_byte (void)
|
|||||||
if (!(i.base_reg->reg_flags & RegRex)
|
if (!(i.base_reg->reg_flags & RegRex)
|
||||||
&& (i.base_reg->reg_num == EBP_REG_NUM
|
&& (i.base_reg->reg_num == EBP_REG_NUM
|
||||||
|| i.base_reg->reg_num == ESP_REG_NUM))
|
|| i.base_reg->reg_num == ESP_REG_NUM))
|
||||||
default_seg = &ss;
|
default_seg = reg_ss;
|
||||||
if (i.base_reg->reg_num == 5 && i.disp_operands == 0)
|
if (i.base_reg->reg_num == 5 && i.disp_operands == 0)
|
||||||
{
|
{
|
||||||
fake_zero_displacement = 1;
|
fake_zero_displacement = 1;
|
||||||
@ -11325,27 +11337,7 @@ i386_att_operand (char *operand_string)
|
|||||||
++op_string;
|
++op_string;
|
||||||
if (*op_string == ':' && r->reg_type.bitfield.class == SReg)
|
if (*op_string == ':' && r->reg_type.bitfield.class == SReg)
|
||||||
{
|
{
|
||||||
switch (r->reg_num)
|
i.seg[i.mem_operands] = r;
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
i.seg[i.mem_operands] = &es;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
i.seg[i.mem_operands] = &cs;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
i.seg[i.mem_operands] = &ss;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
i.seg[i.mem_operands] = &ds;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
i.seg[i.mem_operands] = &fs;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
i.seg[i.mem_operands] = &gs;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Skip the ':' and whitespace. */
|
/* Skip the ':' and whitespace. */
|
||||||
++op_string;
|
++op_string;
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
2021-03-30 Jan Beulich <jbeulich@suse.com>
|
||||||
|
|
||||||
|
* i386-opc.c (cs, ds, ss, es, fs, gs): Delete.
|
||||||
|
(i386_seg_prefixes): New.
|
||||||
|
* i386-opc.h (cs, ds, ss, es, fs, gs): Delete.
|
||||||
|
(i386_seg_prefixes): Declare.
|
||||||
|
|
||||||
2021-03-30 Jan Beulich <jbeulich@suse.com>
|
2021-03-30 Jan Beulich <jbeulich@suse.com>
|
||||||
|
|
||||||
* i386-opc.h (REGNAM_AL, REGNAM_AX, REGNAM_EAX): Delete.
|
* i386-opc.h (REGNAM_AL, REGNAM_AX, REGNAM_EAX): Delete.
|
||||||
|
@ -23,10 +23,12 @@
|
|||||||
#include "i386-opc.h"
|
#include "i386-opc.h"
|
||||||
#include "i386-tbl.h"
|
#include "i386-tbl.h"
|
||||||
|
|
||||||
/* Segment stuff. */
|
/* To be indexed by segment register number. */
|
||||||
const seg_entry cs = { "cs", 0x2e };
|
const unsigned char i386_seg_prefixes[] = {
|
||||||
const seg_entry ds = { "ds", 0x3e };
|
ES_PREFIX_OPCODE,
|
||||||
const seg_entry ss = { "ss", 0x36 };
|
CS_PREFIX_OPCODE,
|
||||||
const seg_entry es = { "es", 0x26 };
|
SS_PREFIX_OPCODE,
|
||||||
const seg_entry fs = { "fs", 0x64 };
|
DS_PREFIX_OPCODE,
|
||||||
const seg_entry gs = { "gs", 0x65 };
|
FS_PREFIX_OPCODE,
|
||||||
|
GS_PREFIX_OPCODE
|
||||||
|
};
|
||||||
|
@ -992,17 +992,4 @@ reg_entry;
|
|||||||
|
|
||||||
extern const reg_entry i386_regtab[];
|
extern const reg_entry i386_regtab[];
|
||||||
extern const unsigned int i386_regtab_size;
|
extern const unsigned int i386_regtab_size;
|
||||||
|
extern const unsigned char i386_seg_prefixes[6];
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
char *seg_name;
|
|
||||||
unsigned int seg_prefix;
|
|
||||||
}
|
|
||||||
seg_entry;
|
|
||||||
|
|
||||||
extern const seg_entry cs;
|
|
||||||
extern const seg_entry ds;
|
|
||||||
extern const seg_entry ss;
|
|
||||||
extern const seg_entry es;
|
|
||||||
extern const seg_entry fs;
|
|
||||||
extern const seg_entry gs;
|
|
||||||
|
Loading…
Reference in New Issue
Block a user