@ -743,7 +743,8 @@ i386_align_code (fragS *fragP, int count)
1. For PROCESSOR_I486 , PROCESSOR_PENTIUM and PROCESSOR_GENERIC32 ,
f32_patt will be used .
2. For PROCESSOR_K8 and PROCESSOR_AMDFAM10 in 64 bit , NOPs with 0x66 prefix will be used .
2. For PROCESSOR_K8 and PROCESSOR_AMDFAM10 in 64 bit , NOPs with
0x66 prefix will be used .
3. For PROCESSOR_CORE2 , alt_long_patt will be used .
4. For PROCESSOR_PENTIUMPRO , PROCESSOR_PENTIUM4 , PROCESSOR_NOCONA ,
PROCESSOR_CORE , PROCESSOR_CORE2 , PROCESSOR_K6 , PROCESSOR_ATHLON
@ -1130,7 +1131,8 @@ set_cpu_arch (int dummy ATTRIBUTE_UNUSED)
cpu_arch_name = cpu_arch [ i ] . name ;
cpu_sub_arch_name = NULL ;
cpu_arch_flags = ( cpu_arch [ i ] . flags
| ( flag_code = = CODE_64BIT ? Cpu64 : CpuNo64 ) ) ;
| ( flag_code = = CODE_64BIT
? Cpu64 : CpuNo64 ) ) ;
cpu_arch_isa = cpu_arch [ i ] . type ;
cpu_arch_isa_flags = cpu_arch [ i ] . flags ;
if ( ! cpu_arch_tune_set )
@ -1902,7 +1904,8 @@ md_assemble (line)
{
/* In case it is "hi" register, give up. */
if ( i . op [ x ] . regs - > reg_num > 3 )
as_bad ( _ ( " can't encode register '%%%s' in an instruction requiring REX prefix. " ) ,
as_bad ( _ ( " can't encode register '%%%s' in an "
" instruction requiring REX prefix. " ) ,
i . op [ x ] . regs - > reg_name ) ;
/* Otherwise it is equivalent to the extended register.
@ -2393,7 +2396,9 @@ optimize_imm (void)
unsigned int mask , allowed = 0 ;
const template * t ;
for ( t = current_templates - > start ; t < current_templates - > end ; + + t )
for ( t = current_templates - > start ;
t < current_templates - > end ;
+ + t )
allowed | = t - > operand_types [ op ] ;
switch ( guess_suffix )
{
@ -2886,7 +2891,8 @@ process_suffix (void)
{
if ( i . tm . opcode_modifier & W )
{
as_bad ( _ ( " no instruction mnemonic suffix given and no register operands; can't size instruction " ) ) ;
as_bad ( _ ( " no instruction mnemonic suffix given and "
" no register operands; can't size instruction " ) ) ;
return 0 ;
}
}
@ -3194,7 +3200,8 @@ finalize_imm (void)
& & overlap0 ! = Imm16 & & overlap0 ! = Imm32S
& & overlap0 ! = Imm32 & & overlap0 ! = Imm64 )
{
as_bad ( _ ( " no instruction mnemonic suffix given; can't determine immediate size " ) ) ;
as_bad ( _ ( " no instruction mnemonic suffix given; "
" can't determine immediate size " ) ) ;
return 0 ;
}
}
@ -3227,7 +3234,9 @@ finalize_imm (void)
& & overlap1 ! = Imm16 & & overlap1 ! = Imm32S
& & overlap1 ! = Imm32 & & overlap1 ! = Imm64 )
{
as_bad ( _ ( " no instruction mnemonic suffix given; can't determine immediate size %x %c " ) , overlap1 , i . suffix ) ;
as_bad ( _ ( " no instruction mnemonic suffix given; "
" can't determine immediate size %x %c " ) ,
overlap1 , i . suffix ) ;
return 0 ;
}
}
@ -3264,6 +3273,20 @@ process_operands (void)
}
if ( i . tm . opcode_modifier & ShortForm )
{
if ( i . types [ 0 ] & ( SReg2 | SReg3 ) )
{
if ( i . tm . base_opcode = = POP_SEG_SHORT
& & i . op [ 0 ] . regs - > reg_num = = 1 )
{
as_bad ( _ ( " you can't `pop %%cs' " ) ) ;
return 0 ;
}
i . tm . base_opcode | = ( i . op [ 0 ] . regs - > reg_num < < 3 ) ;
if ( ( i . op [ 0 ] . regs - > reg_flags & RegRex ) ! = 0 )
i . rex | = REX_EXTZ ;
}
else
{
/* The register or float register operand is in operand 0 or 1. */
unsigned int op = ( i . types [ 0 ] & ( Reg | FloatReg ) ) ? 0 : 1 ;
@ -3290,6 +3313,7 @@ process_operands (void)
}
}
}
}
else if ( i . tm . opcode_modifier & Modrm )
{
/* The opcode is completed (modulo i.tm.extension_opcode which
@ -3298,18 +3322,6 @@ process_operands (void)
default_seg = build_modrm_byte ( ) ;
}
else if ( i . tm . opcode_modifier & ( Seg2ShortForm | Seg3ShortForm ) )
{
if ( i . tm . base_opcode = = POP_SEG_SHORT
& & i . op [ 0 ] . regs - > reg_num = = 1 )
{
as_bad ( _ ( " you can't `pop %%cs' " ) ) ;
return 0 ;
}
i . tm . base_opcode | = ( i . op [ 0 ] . regs - > reg_num < < 3 ) ;
if ( ( i . op [ 0 ] . regs - > reg_flags & RegRex ) ! = 0 )
i . rex | = REX_EXTZ ;
}
else if ( ( i . tm . base_opcode & ~ ( D | W ) ) = = MOV_AX_DISP32 )
{
default_seg = & ds ;
@ -4277,23 +4289,57 @@ lex_got (enum bfd_reloc_code_real *reloc,
const enum bfd_reloc_code_real rel [ 2 ] ;
const unsigned int types64 ;
} gotrel [ ] = {
{ " PLTOFF " , { 0 , BFD_RELOC_X86_64_PLTOFF64 } , Imm64 } ,
{ " PLT " , { BFD_RELOC_386_PLT32 , BFD_RELOC_X86_64_PLT32 } , Imm32 | Imm32S | Disp32 } ,
{ " GOTPLT " , { 0 , BFD_RELOC_X86_64_GOTPLT64 } , Imm64 | Disp64 } ,
{ " GOTOFF " , { BFD_RELOC_386_GOTOFF , BFD_RELOC_X86_64_GOTOFF64 } , Imm64 | Disp64 } ,
{ " GOTPCREL " , { 0 , BFD_RELOC_X86_64_GOTPCREL } , Imm32 | Imm32S | Disp32 } ,
{ " TLSGD " , { BFD_RELOC_386_TLS_GD , BFD_RELOC_X86_64_TLSGD } , Imm32 | Imm32S | Disp32 } ,
{ " TLSLDM " , { BFD_RELOC_386_TLS_LDM , 0 } , 0 } ,
{ " TLSLD " , { 0 , BFD_RELOC_X86_64_TLSLD } , Imm32 | Imm32S | Disp32 } ,
{ " GOTTPOFF " , { BFD_RELOC_386_TLS_IE_32 , BFD_RELOC_X86_64_GOTTPOFF } , Imm32 | Imm32S | Disp32 } ,
{ " TPOFF " , { BFD_RELOC_386_TLS_LE_32 , BFD_RELOC_X86_64_TPOFF32 } , Imm32 | Imm32S | Imm64 | Disp32 | Disp64 } ,
{ " NTPOFF " , { BFD_RELOC_386_TLS_LE , 0 } , 0 } ,
{ " DTPOFF " , { BFD_RELOC_386_TLS_LDO_32 , BFD_RELOC_X86_64_DTPOFF32 } , Imm32 | Imm32S | Imm64 | Disp32 | Disp64 } ,
{ " GOTNTPOFF " , { BFD_RELOC_386_TLS_GOTIE , 0 } , 0 } ,
{ " INDNTPOFF " , { BFD_RELOC_386_TLS_IE , 0 } , 0 } ,
{ " GOT " , { BFD_RELOC_386_GOT32 , BFD_RELOC_X86_64_GOT32 } , Imm32 | Imm32S | Disp32 | Imm64 } ,
{ " TLSDESC " , { BFD_RELOC_386_TLS_GOTDESC , BFD_RELOC_X86_64_GOTPC32_TLSDESC } , Imm32 | Imm32S | Disp32 } ,
{ " TLSCALL " , { BFD_RELOC_386_TLS_DESC_CALL , BFD_RELOC_X86_64_TLSDESC_CALL } , Imm32 | Imm32S | Disp32 }
{ " PLTOFF " , { 0 ,
BFD_RELOC_X86_64_PLTOFF64 } ,
Imm64 } ,
{ " PLT " , { BFD_RELOC_386_PLT32 ,
BFD_RELOC_X86_64_PLT32 } ,
Imm32 | Imm32S | Disp32 } ,
{ " GOTPLT " , { 0 ,
BFD_RELOC_X86_64_GOTPLT64 } ,
Imm64 | Disp64 } ,
{ " GOTOFF " , { BFD_RELOC_386_GOTOFF ,
BFD_RELOC_X86_64_GOTOFF64 } ,
Imm64 | Disp64 } ,
{ " GOTPCREL " , { 0 ,
BFD_RELOC_X86_64_GOTPCREL } ,
Imm32 | Imm32S | Disp32 } ,
{ " TLSGD " , { BFD_RELOC_386_TLS_GD ,
BFD_RELOC_X86_64_TLSGD } ,
Imm32 | Imm32S | Disp32 } ,
{ " TLSLDM " , { BFD_RELOC_386_TLS_LDM ,
0 } ,
0 } ,
{ " TLSLD " , { 0 ,
BFD_RELOC_X86_64_TLSLD } ,
Imm32 | Imm32S | Disp32 } ,
{ " GOTTPOFF " , { BFD_RELOC_386_TLS_IE_32 ,
BFD_RELOC_X86_64_GOTTPOFF } ,
Imm32 | Imm32S | Disp32 } ,
{ " TPOFF " , { BFD_RELOC_386_TLS_LE_32 ,
BFD_RELOC_X86_64_TPOFF32 } ,
Imm32 | Imm32S | Imm64 | Disp32 | Disp64 } ,
{ " NTPOFF " , { BFD_RELOC_386_TLS_LE ,
0 } ,
0 } ,
{ " DTPOFF " , { BFD_RELOC_386_TLS_LDO_32 ,
BFD_RELOC_X86_64_DTPOFF32 } ,
Imm32 | Imm32S | Imm64 | Disp32 | Disp64 } ,
{ " GOTNTPOFF " , { BFD_RELOC_386_TLS_GOTIE ,
0 } ,
0 } ,
{ " INDNTPOFF " , { BFD_RELOC_386_TLS_IE ,
0 } ,
0 } ,
{ " GOT " , { BFD_RELOC_386_GOT32 ,
BFD_RELOC_X86_64_GOT32 } ,
Imm32 | Imm32S | Disp32 | Imm64 } ,
{ " TLSDESC " , { BFD_RELOC_386_TLS_GOTDESC ,
BFD_RELOC_X86_64_GOTPC32_TLSDESC } ,
Imm32 | Imm32S | Disp32 } ,
{ " TLSCALL " , { BFD_RELOC_386_TLS_DESC_CALL ,
BFD_RELOC_X86_64_TLSDESC_CALL } ,
Imm32 | Imm32S | Disp32 }
} ;
char * cp ;
unsigned int j ;
@ -4483,9 +4529,10 @@ i386_immediate (char *imm_start)
/* Size it properly later. */
i . types [ this_operand ] | = Imm64 ;
/* If BFD64, sign extend val. */
if ( ! use_rela_relocations )
if ( ( exp - > X_add_number & ~ ( ( ( addressT ) 2 < < 31 ) - 1 ) ) = = 0 )
exp - > X_add_number = ( exp - > X_add_number ^ ( ( addressT ) 1 < < 31 ) ) - ( ( addressT ) 1 < < 31 ) ;
if ( ! use_rela_relocations
& & ( exp - > X_add_number & ~ ( ( ( addressT ) 2 < < 31 ) - 1 ) ) = = 0 )
exp - > X_add_number
= ( exp - > X_add_number ^ ( ( addressT ) 1 < < 31 ) ) - ( ( addressT ) 1 < < 31 ) ;
}
# if (defined (OBJ_AOUT) || defined (OBJ_MAYBE_AOUT))
else if ( OUTPUT_FLAVOR = = bfd_target_aout_flavour
@ -4837,7 +4884,8 @@ i386_index_check (const char *operand_string)
FIXME . There doesn ' t seem to be any real need for separate
Disp16 and Disp32 flags . The same goes for Imm16 and Imm32 .
Removing them would probably clean up the code quite a lot . */
if ( flag_code ! = CODE_64BIT & & ( i . types [ this_operand ] & ( Disp16 | Disp32 ) ) )
if ( flag_code ! = CODE_64BIT
& & ( i . types [ this_operand ] & ( Disp16 | Disp32 ) ) )
i . types [ this_operand ] ^ = ( Disp16 | Disp32 ) ;
fudged = 1 ;
goto tryprefix ;
@ -5016,7 +5064,8 @@ i386_operand (char *operand_string)
+ + base_string ;
if ( * base_string = = ' , '
| | ( ( i . base_reg = parse_register ( base_string , & end_op ) ) ! = NULL ) )
| | ( ( i . base_reg = parse_register ( base_string , & end_op ) )
! = NULL ) )
{
displacement_string_end = temp_string ;
@ -5036,7 +5085,8 @@ i386_operand (char *operand_string)
if ( is_space_char ( * base_string ) )
+ + base_string ;
if ( ( i . index_reg = parse_register ( base_string , & end_op ) ) ! = NULL )
if ( ( i . index_reg = parse_register ( base_string , & end_op ) )
! = NULL )
{
base_string = end_op ;
if ( is_space_char ( * base_string ) )
@ -5049,7 +5099,8 @@ i386_operand (char *operand_string)
}
else if ( * base_string ! = ' ) ' )
{
as_bad ( _ ( " expecting `,' or `)' after index register in `%s' " ) ,
as_bad ( _ ( " expecting `,' or `)' "
" after index register in `%s' " ) ,
operand_string ) ;
return 0 ;
}
@ -5073,21 +5124,24 @@ i386_operand (char *operand_string)
+ + base_string ;
if ( * base_string ! = ' ) ' )
{
as_bad ( _ ( " expecting `)' after scale factor in `%s' " ) ,
as_bad ( _ ( " expecting `)' "
" after scale factor in `%s' " ) ,
operand_string ) ;
return 0 ;
}
}
else if ( ! i . index_reg )
{
as_bad ( _ ( " expecting index register or scale factor after `,'; got '%c' " ) ,
as_bad ( _ ( " expecting index register or scale factor "
" after `,'; got '%c' " ) ,
* base_string ) ;
return 0 ;
}
}
else if ( * base_string ! = ' ) ' )
{
as_bad ( _ ( " expecting `,' or `)' after base register in `%s' " ) ,
as_bad ( _ ( " expecting `,' or `)' "
" after base register in `%s' " ) ,
operand_string ) ;
return 0 ;
}
@ -5303,7 +5357,8 @@ md_convert_frag (abfd, sec, fragP)
{
if ( no_cond_jump_promotion
& & TYPE_FROM_RELAX_STATE ( fragP - > fr_subtype ) ! = UNCOND_JUMP )
as_warn_where ( fragP - > fr_file , fragP - > fr_line , _ ( " long jump required " ) ) ;
as_warn_where ( fragP - > fr_file , fragP - > fr_line ,
_ ( " long jump required " ) ) ;
switch ( fragP - > fr_subtype )
{
@ -5730,7 +5785,8 @@ parse_register (char *reg_string, char **end_op)
const expressionS * e = symbol_get_value_expression ( symbolP ) ;
know ( e - > X_op = = O_register ) ;
know ( e - > X_add_number > = 0 & & ( valueT ) e - > X_add_number < ARRAY_SIZE ( i386_regtab ) ) ;
know ( e - > X_add_number > = 0
& & ( valueT ) e - > X_add_number < ARRAY_SIZE ( i386_regtab ) ) ;
r = i386_regtab + e - > X_add_number ;
* end_op = input_line_pointer ;
}
@ -6717,7 +6773,9 @@ intel_e05 (void)
if ( ! intel_e06 ( ) )
return 0 ;
if ( cur_token . code = = ' & ' | | cur_token . code = = ' | ' | | cur_token . code = = ' ^ ' )
if ( cur_token . code = = ' & '
| | cur_token . code = = ' | '
| | cur_token . code = = ' ^ ' )
{
char str [ 2 ] ;
@ -6752,7 +6810,9 @@ intel_e06 (void)
if ( ! intel_e09 ( ) )
return 0 ;
if ( cur_token . code = = ' * ' | | cur_token . code = = ' / ' | | cur_token . code = = ' % ' )
if ( cur_token . code = = ' * '
| | cur_token . code = = ' / '
| | cur_token . code = = ' % ' )
{
char str [ 2 ] ;
@ -7064,7 +7124,8 @@ intel_bracket_expr (void)
/* Defer the warning until all of the operand was parsed. */
intel_parser . is_mem = - 1 ;
else if ( ! quiet_warnings )
as_warn ( _ ( " `[%.*s]' taken to mean just `%.*s' " ) , len , start , len , start ) ;
as_warn ( _ ( " `[%.*s]' taken to mean just `%.*s' " ) ,
len , start , len , start ) ;
}
}
intel_parser . op_modifier | = was_offset ;
@ -7154,7 +7215,8 @@ intel_e11 (void)
{
if ( ! ( reg - > reg_type & ( SReg2 | SReg3 ) ) )
{
as_bad ( _ ( " `%s' is not a valid segment register " ) , reg - > reg_name ) ;
as_bad ( _ ( " `%s' is not a valid segment register " ) ,
reg - > reg_name ) ;
return 0 ;
}
else if ( i . seg [ i . mem_operands ] )
@ -7344,7 +7406,8 @@ intel_e11 (void)
/* Get the next token to check for register scaling. */
intel_match_token ( cur_token . code ) ;
/* Check if this constant is a scaling factor for an index register. */
/* Check if this constant is a scaling factor for an
index register . */
if ( cur_token . code = = ' * ' )
{
if ( intel_match_token ( ' * ' ) & & cur_token . code = = T_REG )
@ -7353,14 +7416,17 @@ intel_e11 (void)
if ( ! intel_parser . in_bracket )
{
as_bad ( _ ( " Register scaling only allowed in memory operands " ) ) ;
as_bad ( _ ( " Register scaling only allowed "
" in memory operands " ) ) ;
return 0 ;
}
if ( reg - > reg_type & Reg16 ) /* Disallow things like [1*si]. */
reg = i386_regtab + REGNAM_AX + 4 ; /* sp is invalid as index */
/* Disallow things like [1*si].
sp and esp are invalid as index . */
if ( reg - > reg_type & Reg16 )
reg = i386_regtab + REGNAM_AX + 4 ;
else if ( i . index_reg )
reg = i386_regtab + REGNAM_EAX + 4 ; /* esp is invalid as index */
reg = i386_regtab + REGNAM_EAX + 4 ;
/* The constant is followed by `* reg', so it must be
a valid scale . */