mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-09-11 16:46:14 +08:00
gas/
* config/tc-mips.h (mips_nop_opcode): Declare. (NOP_OPCODE): Define. (mips_segment_info): New structure. (TC_SEGMENT_INFO_TYPE): Use it instead of insn_label_list. * config/tc-mips.c (label_list): Adjust for new TC_SEGMENT_INFO_TYPE. (mips_record_mips16_mode): New function. (install_insn): Call it. (mips_align): Likewise. Turn the fill argument into an "int *". Use frag_align_code for code segments if no fill data is given. (s_align): Adjust call accordingly. (mips_nop_opcode): New function. (mips_handle_align): Use the first variable byte to decide which nop sequence is needed. Use md_number_to_chars and mips16_nop_insn. gas/testsuite/ * gas/mips/align2.s, gas/mips/align2.d, gas/mips/align2-el.d: New tests. * gas/mips/mips.exp: Run them.
This commit is contained in:
@ -1,3 +1,19 @@
|
|||||||
|
2007-12-10 Richard Sandiford <rsandifo@nildram.co.uk>
|
||||||
|
|
||||||
|
* config/tc-mips.h (mips_nop_opcode): Declare.
|
||||||
|
(NOP_OPCODE): Define.
|
||||||
|
(mips_segment_info): New structure.
|
||||||
|
(TC_SEGMENT_INFO_TYPE): Use it instead of insn_label_list.
|
||||||
|
* config/tc-mips.c (label_list): Adjust for new TC_SEGMENT_INFO_TYPE.
|
||||||
|
(mips_record_mips16_mode): New function.
|
||||||
|
(install_insn): Call it.
|
||||||
|
(mips_align): Likewise. Turn the fill argument into an "int *".
|
||||||
|
Use frag_align_code for code segments if no fill data is given.
|
||||||
|
(s_align): Adjust call accordingly.
|
||||||
|
(mips_nop_opcode): New function.
|
||||||
|
(mips_handle_align): Use the first variable byte to decide which
|
||||||
|
nop sequence is needed. Use md_number_to_chars and mips16_nop_insn.
|
||||||
|
|
||||||
2007-12-07 Bob Wilson <bob.wilson@acm.org>
|
2007-12-07 Bob Wilson <bob.wilson@acm.org>
|
||||||
|
|
||||||
* config/tc-xtensa.c (O_pcrel): Define.
|
* config/tc-xtensa.c (O_pcrel): Define.
|
||||||
|
@ -1185,7 +1185,7 @@ struct insn_label_list
|
|||||||
};
|
};
|
||||||
|
|
||||||
static struct insn_label_list *free_insn_labels;
|
static struct insn_label_list *free_insn_labels;
|
||||||
#define label_list tc_segment_info_data
|
#define label_list tc_segment_info_data.labels
|
||||||
|
|
||||||
static void mips_clear_insn_labels (void);
|
static void mips_clear_insn_labels (void);
|
||||||
|
|
||||||
@ -1310,6 +1310,18 @@ create_insn (struct mips_cl_insn *insn, const struct mips_opcode *mo)
|
|||||||
insn->mips16_absolute_jump_p = 0;
|
insn->mips16_absolute_jump_p = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Record the current MIPS16 mode in now_seg. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
mips_record_mips16_mode (void)
|
||||||
|
{
|
||||||
|
segment_info_type *si;
|
||||||
|
|
||||||
|
si = seg_info (now_seg);
|
||||||
|
if (si->tc_segment_info_data.mips16 != mips_opts.mips16)
|
||||||
|
si->tc_segment_info_data.mips16 = mips_opts.mips16;
|
||||||
|
}
|
||||||
|
|
||||||
/* Install INSN at the location specified by its "frag" and "where" fields. */
|
/* Install INSN at the location specified by its "frag" and "where" fields. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1332,6 +1344,7 @@ install_insn (const struct mips_cl_insn *insn)
|
|||||||
}
|
}
|
||||||
md_number_to_chars (f, insn->insn_opcode, 2);
|
md_number_to_chars (f, insn->insn_opcode, 2);
|
||||||
}
|
}
|
||||||
|
mips_record_mips16_mode ();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Move INSN to offset WHERE in FRAG. Adjust the fixups accordingly
|
/* Move INSN to offset WHERE in FRAG. Adjust the fixups accordingly
|
||||||
@ -11994,14 +12007,22 @@ get_symbol (void)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Align the current frag to a given power of two. The MIPS assembler
|
/* Align the current frag to a given power of two. If a particular
|
||||||
also automatically adjusts any preceding label. */
|
fill byte should be used, FILL points to an integer that contains
|
||||||
|
that byte, otherwise FILL is null.
|
||||||
|
|
||||||
|
The MIPS assembler also automatically adjusts any preceding
|
||||||
|
label. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mips_align (int to, int fill, symbolS *label)
|
mips_align (int to, int *fill, symbolS *label)
|
||||||
{
|
{
|
||||||
mips_emit_delays ();
|
mips_emit_delays ();
|
||||||
frag_align (to, fill, 0);
|
mips_record_mips16_mode ();
|
||||||
|
if (fill == NULL && subseg_text_p (now_seg))
|
||||||
|
frag_align_code (to, 0);
|
||||||
|
else
|
||||||
|
frag_align (to, fill ? *fill : 0, 0);
|
||||||
record_alignment (now_seg, to);
|
record_alignment (now_seg, to);
|
||||||
if (label != NULL)
|
if (label != NULL)
|
||||||
{
|
{
|
||||||
@ -12017,8 +12038,7 @@ mips_align (int to, int fill, symbolS *label)
|
|||||||
static void
|
static void
|
||||||
s_align (int x ATTRIBUTE_UNUSED)
|
s_align (int x ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
int temp;
|
int temp, fill_value, *fill_ptr;
|
||||||
long temp_fill;
|
|
||||||
long max_alignment = 28;
|
long max_alignment = 28;
|
||||||
|
|
||||||
/* o Note that the assembler pulls down any immediately preceding label
|
/* o Note that the assembler pulls down any immediately preceding label
|
||||||
@ -12040,17 +12060,18 @@ s_align (int x ATTRIBUTE_UNUSED)
|
|||||||
if (*input_line_pointer == ',')
|
if (*input_line_pointer == ',')
|
||||||
{
|
{
|
||||||
++input_line_pointer;
|
++input_line_pointer;
|
||||||
temp_fill = get_absolute_expression ();
|
fill_value = get_absolute_expression ();
|
||||||
|
fill_ptr = &fill_value;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
temp_fill = 0;
|
fill_ptr = 0;
|
||||||
if (temp)
|
if (temp)
|
||||||
{
|
{
|
||||||
segment_info_type *si = seg_info (now_seg);
|
segment_info_type *si = seg_info (now_seg);
|
||||||
struct insn_label_list *l = si->label_list;
|
struct insn_label_list *l = si->label_list;
|
||||||
/* Auto alignment should be switched on by next section change. */
|
/* Auto alignment should be switched on by next section change. */
|
||||||
auto_align = 1;
|
auto_align = 1;
|
||||||
mips_align (temp, (int) temp_fill, l != NULL ? l->label : NULL);
|
mips_align (temp, fill_ptr, l != NULL ? l->label : NULL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -14321,36 +14342,40 @@ static procS cur_proc;
|
|||||||
static procS *cur_proc_ptr;
|
static procS *cur_proc_ptr;
|
||||||
static int numprocs;
|
static int numprocs;
|
||||||
|
|
||||||
/* Fill in an rs_align_code fragment. */
|
/* Implement NOP_OPCODE. We encode a MIPS16 nop as "1" and a normal
|
||||||
|
nop as "0". */
|
||||||
|
|
||||||
|
char
|
||||||
|
mips_nop_opcode (void)
|
||||||
|
{
|
||||||
|
return seg_info (now_seg)->tc_segment_info_data.mips16;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill in an rs_align_code fragment. This only needs to do something
|
||||||
|
for MIPS16 code, where 0 is not a nop. */
|
||||||
|
|
||||||
void
|
void
|
||||||
mips_handle_align (fragS *fragp)
|
mips_handle_align (fragS *fragp)
|
||||||
{
|
{
|
||||||
|
char *p;
|
||||||
|
|
||||||
if (fragp->fr_type != rs_align_code)
|
if (fragp->fr_type != rs_align_code)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (mips_opts.mips16)
|
p = fragp->fr_literal + fragp->fr_fix;
|
||||||
|
if (*p)
|
||||||
{
|
{
|
||||||
static const unsigned char be_nop[] = { 0x65, 0x00 };
|
|
||||||
static const unsigned char le_nop[] = { 0x00, 0x65 };
|
|
||||||
|
|
||||||
int bytes;
|
int bytes;
|
||||||
char *p;
|
|
||||||
|
|
||||||
bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
|
bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
|
||||||
p = fragp->fr_literal + fragp->fr_fix;
|
|
||||||
|
|
||||||
if (bytes & 1)
|
if (bytes & 1)
|
||||||
{
|
{
|
||||||
*p++ = 0;
|
*p++ = 0;
|
||||||
fragp->fr_fix++;
|
fragp->fr_fix++;
|
||||||
}
|
}
|
||||||
|
md_number_to_chars (p, mips16_nop_insn.insn_opcode, 2);
|
||||||
memcpy (p, (target_big_endian ? be_nop : le_nop), 2);
|
|
||||||
fragp->fr_var = 2;
|
fragp->fr_var = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* For mips32, a nop is a zero, which we trivially get by doing nothing. */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -53,13 +53,20 @@ extern int mips_relax_frag (asection *, struct frag *, long);
|
|||||||
#define md_undefined_symbol(name) (0)
|
#define md_undefined_symbol(name) (0)
|
||||||
#define md_operand(x)
|
#define md_operand(x)
|
||||||
|
|
||||||
|
extern char mips_nop_opcode (void);
|
||||||
|
#define NOP_OPCODE (mips_nop_opcode ())
|
||||||
|
|
||||||
extern void mips_handle_align (struct frag *);
|
extern void mips_handle_align (struct frag *);
|
||||||
#define HANDLE_ALIGN(fragp) mips_handle_align (fragp)
|
#define HANDLE_ALIGN(fragp) mips_handle_align (fragp)
|
||||||
|
|
||||||
#define MAX_MEM_FOR_RS_ALIGN_CODE (1 + 2)
|
#define MAX_MEM_FOR_RS_ALIGN_CODE (1 + 2)
|
||||||
|
|
||||||
struct insn_label_list;
|
struct insn_label_list;
|
||||||
#define TC_SEGMENT_INFO_TYPE struct insn_label_list *
|
struct mips_segment_info {
|
||||||
|
struct insn_label_list *labels;
|
||||||
|
unsigned int mips16 : 1;
|
||||||
|
};
|
||||||
|
#define TC_SEGMENT_INFO_TYPE struct mips_segment_info
|
||||||
|
|
||||||
/* This field is nonzero if the symbol is the target of a MIPS16 jump. */
|
/* This field is nonzero if the symbol is the target of a MIPS16 jump. */
|
||||||
#define TC_SYMFIELD_TYPE int
|
#define TC_SYMFIELD_TYPE int
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
2007-12-10 Richard Sandiford <rsandifo@nildram.co.uk>
|
||||||
|
|
||||||
|
* gas/mips/align2.s, gas/mips/align2.d, gas/mips/align2-el.d: New
|
||||||
|
tests.
|
||||||
|
* gas/mips/mips.exp: Run them.
|
||||||
|
|
||||||
2007-12-07 Bob Wilson <bob.wilson@acm.org>
|
2007-12-07 Bob Wilson <bob.wilson@acm.org>
|
||||||
|
|
||||||
* gas/xtensa/all.exp: Run new pcrel test.
|
* gas/xtensa/all.exp: Run new pcrel test.
|
||||||
|
42
gas/testsuite/gas/mips/align2-el.d
Normal file
42
gas/testsuite/gas/mips/align2-el.d
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
# source: align2.s
|
||||||
|
# as: -EL
|
||||||
|
# objdump: -dr
|
||||||
|
|
||||||
|
.* file format .*
|
||||||
|
|
||||||
|
Disassembly of section \.text:
|
||||||
|
|
||||||
|
00000000 <f1>:
|
||||||
|
0: 4a01 addiu v0,1
|
||||||
|
2: 6500 nop
|
||||||
|
4: 6500 nop
|
||||||
|
6: 6500 nop
|
||||||
|
8: 4b01 addiu v1,1
|
||||||
|
a: 6500 nop
|
||||||
|
|
||||||
|
0000000c <f2>:
|
||||||
|
c: 24420001 addiu v0,v0,1
|
||||||
|
10: 24630001 addiu v1,v1,1
|
||||||
|
\.\.\.
|
||||||
|
20: 24840001 addiu a0,a0,1
|
||||||
|
24: 00000000 nop
|
||||||
|
|
||||||
|
00000028 <f3>:
|
||||||
|
28: 4001 addiu s0,s0,1
|
||||||
|
2a: 6500 nop
|
||||||
|
2c: 6500 nop
|
||||||
|
2e: 6500 nop
|
||||||
|
30: 6500 nop
|
||||||
|
32: 6500 nop
|
||||||
|
34: 6500 nop
|
||||||
|
36: 6500 nop
|
||||||
|
38: 6500 nop
|
||||||
|
3a: 6500 nop
|
||||||
|
3c: 6500 nop
|
||||||
|
3e: 6500 nop
|
||||||
|
|
||||||
|
Disassembly of section \.text\.a:
|
||||||
|
|
||||||
|
00000000 <f4>:
|
||||||
|
0: 24a50001 addiu a1,a1,1
|
||||||
|
\.\.\.
|
41
gas/testsuite/gas/mips/align2.d
Normal file
41
gas/testsuite/gas/mips/align2.d
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# as: -EB
|
||||||
|
# objdump: -dr
|
||||||
|
|
||||||
|
.* file format .*
|
||||||
|
|
||||||
|
Disassembly of section \.text:
|
||||||
|
|
||||||
|
00000000 <f1>:
|
||||||
|
0: 4a01 addiu v0,1
|
||||||
|
2: 6500 nop
|
||||||
|
4: 6500 nop
|
||||||
|
6: 6500 nop
|
||||||
|
8: 4b01 addiu v1,1
|
||||||
|
a: 6500 nop
|
||||||
|
|
||||||
|
0000000c <f2>:
|
||||||
|
c: 24420001 addiu v0,v0,1
|
||||||
|
10: 24630001 addiu v1,v1,1
|
||||||
|
\.\.\.
|
||||||
|
20: 24840001 addiu a0,a0,1
|
||||||
|
24: 00000000 nop
|
||||||
|
|
||||||
|
00000028 <f3>:
|
||||||
|
28: 4001 addiu s0,s0,1
|
||||||
|
2a: 6500 nop
|
||||||
|
2c: 6500 nop
|
||||||
|
2e: 6500 nop
|
||||||
|
30: 6500 nop
|
||||||
|
32: 6500 nop
|
||||||
|
34: 6500 nop
|
||||||
|
36: 6500 nop
|
||||||
|
38: 6500 nop
|
||||||
|
3a: 6500 nop
|
||||||
|
3c: 6500 nop
|
||||||
|
3e: 6500 nop
|
||||||
|
|
||||||
|
Disassembly of section \.text\.a:
|
||||||
|
|
||||||
|
00000000 <f4>:
|
||||||
|
0: 24a50001 addiu a1,a1,1
|
||||||
|
\.\.\.
|
35
gas/testsuite/gas/mips/align2.s
Normal file
35
gas/testsuite/gas/mips/align2.s
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
.text
|
||||||
|
.align 5
|
||||||
|
.type f1,@function
|
||||||
|
f1:
|
||||||
|
.set mips16
|
||||||
|
addiu $2,1
|
||||||
|
.align 3
|
||||||
|
addiu $3,1
|
||||||
|
.size f1,.-f1
|
||||||
|
|
||||||
|
.align 2
|
||||||
|
.set nomips16
|
||||||
|
.type f2,@function
|
||||||
|
f2:
|
||||||
|
addiu $2,$2,1
|
||||||
|
addiu $3,$3,1
|
||||||
|
.align 4
|
||||||
|
addiu $4,$4,1
|
||||||
|
.align 3
|
||||||
|
.size f2,.-f2
|
||||||
|
|
||||||
|
.set mips16
|
||||||
|
.type f3,@function
|
||||||
|
f3:
|
||||||
|
addiu $16,$16,1
|
||||||
|
.align 3
|
||||||
|
.size f3,.-f3
|
||||||
|
|
||||||
|
.section .text.a,"ax",@progbits
|
||||||
|
.align 4
|
||||||
|
.set nomips16
|
||||||
|
.type f4,@function
|
||||||
|
f4:
|
||||||
|
addiu $5,$5,1
|
||||||
|
.size f4,.-f4
|
@ -786,5 +786,7 @@ if { [istarget mips*-*-vxworks*] } {
|
|||||||
|
|
||||||
run_dump_test "noreorder"
|
run_dump_test "noreorder"
|
||||||
run_dump_test "align"
|
run_dump_test "align"
|
||||||
|
run_dump_test "align2"
|
||||||
|
run_dump_test "align2-el"
|
||||||
run_dump_test "odd-float"
|
run_dump_test "odd-float"
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user