This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: assembler relaxation
Hi Nick,
md_convert_frag (abfd, sec, fragp)
{
......
......
case 6:
value = (long) (target_address - (address_of_var_part + 4)) + 4;
value >>= 1;
switch (opcodep[0])
{
case BEZ:
//printf("BEZ 16 value = %d\n",value);
opcodep[2] = 0x54; //emit beq, insertng its opcode
break;
case BNEZ:
//printf("BNEZ 16 value = %d\n",value);
opcodep[2] = 0x94; //emit bne, insertng its opcode
break;
}
opcodep[0] = 0x7; //insert cmp instruction instead of bez
opcodep[3] = ( value & 0xff );//insert offset
fixp = fix_new (fragp, fragp->fr_fix, 4, fragp->fr_symbol,
fragp->fr_offset, 1, BFD_RELOC_RPINE_S8_PCREL);
fixp->fx_pcrel_adjust = 2;
fragp->fr_fix += 2;
I am sending the part of md_convert frag.
we are trying to split
bez r0,label(branch if zero) instruction
with
cmp r0,#0 (compare)
beq label (branch if equal) instructions.
I am able to see that the above code is placing correct opcode at that
place but at the end we are seeing 00000000 in few cases.
example:
***************************************************
bez r0,L1 (if L1 > 5bits)
generate:
cmp r0,#0
beq L1
*********************************************************
I am pasting the bench mark code snippet of cg_compiler_opensrc (I have
compiled support.c file with -c option)
file: support.s
=============================================
ldw r6,r15,#16
ldw r5,r15,#24
or r6,r5
*bez r6,.L503*
ldw r1,r15,#20
*bez r1,.L523*
ldw r2,r15,#12
===============================================
objdump output after (rpine-as support.s then rpine-objdump a.out)
---------------------------------------------------------------------------------------------------
1dce: 17 c1 0000c117 ldw r6,sp,#0x10
1dd0: 97 a1 0000a197 ldw r5,sp,#0x18
1dd2: a3 65 000065a3 or r6,r5
1dd4: 07 c0 0000c007 cmp r6,#0x0
1dd6: 00 00
00000000* -----------------> issue
at this line*
1dd8: 57 21 00002157 ldw r1,sp,#0x14
*/1dda: 07 20 00002007 cmp r1,#0x0
------------------------> these two
instructions are generated correctly instead of bez
1ddc: 94 9f 00009f94 beq 1d1a
<DeclareFunc+0x56>/*
---------------------------------------------------------------------------------------------------------
I have gone through the target files and up to that end of the target
file it has the (beq) opcode but at the finally it is appending zero.
Can you suggest where to look in to it. Are there any other documents
other then internals I need to go through.
Thanks,
Nagaraju M
Nick Clifton wrote:
Hi Nagaraju,
I have ported Binutils to a new port. My problem is that in a
16-bit instruction if the constant range is exceeded then I need to
emit 2 instructions. I have referred other architectures and did it
and my assembler is generating instructions them. While running some
bench mark codes it is observed instead of generating two
instructions it is generating 1-st instruction correctly and for
other instruction it is appending Zero's as a result it got struck up.
Without access to the source code for your new port is hard to give
specific advice[1] but in general what you need to do is to look at
the where these instructions are generated/inserted and determine why
the second instruction is using zeroes.
Note - normally relaxation works the other way. That is it normally
removes instructions rather than adding them. Thus I would have
expected that the default behaviour be for the compiler (or user, if
we are talking about hand generated assembler source files) to
generate the two instruction sequence, and for the assembler to relax
this to just one instruction if it can show that this will work.
Cheers
Nick
[1] I am not asking for a copy of the source code - I would rather
that you debug the problem yourself, possibly with some help from this
list. Posting code fragments and more detailed examples of the
problem is a good idea though.