* [gas] new port advice
@ 2015-04-07 15:47 Peter Breuer
2015-04-08 15:31 ` Nicholas Clifton
0 siblings, 1 reply; 5+ messages in thread
From: Peter Breuer @ 2015-04-07 15:47 UTC (permalink / raw)
To: binutils
Is there a pointer for me out there on how to do a little modification
of gas for a certain architecture?
I've read the documentation, googled, perused the source, and made
changes that result in objdump understanding and printing a new
instruction I've added. Now ...
I want to change gas's handling of addi (and other instructions with
immediate data) so that it is treated like a macro that causes three
new machine code instructions to be emitted instead of just the one
old one. Thus
addi r1,r2,0x345 -> newins1 0x3;newins2 0x4;addi r1,r2,0x5
That should be turned on and off by a directive in the assembler.
Which file(s) do I twiddle?
Yes, I could do this by changing the c compiler to output the intended
assembler in the first place. I'll try this first.
Advice gratefully received
PTB
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [gas] new port advice
2015-04-07 15:47 [gas] new port advice Peter Breuer
@ 2015-04-08 15:31 ` Nicholas Clifton
2015-04-08 20:31 ` Peter Breuer
0 siblings, 1 reply; 5+ messages in thread
From: Nicholas Clifton @ 2015-04-08 15:31 UTC (permalink / raw)
To: Peter.T.Breuer, binutils
Hi Peter,
> I want to change gas's handling of addi (and other instructions with
> immediate data) so that it is treated like a macro that causes three
> new machine code instructions to be emitted instead of just the one
> old one. Thus
>
> addi r1,r2,0x345 -> newins1 0x3;newins2 0x4;addi r1,r2,0x5
>
> That should be turned on and off by a directive in the assembler.
>
> Which file(s) do I twiddle?
gas/config/tc-<your arch>.c
You will probably want to update md_assemble() in that file, (or one of
its children), so that it detects the macro instruction and generates
the correct sequence. There are several other architectures that do
this kind of thing (eg: MIPS, RL78) so examining other tc-*.c files may
help.
Cheers
Nick
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [gas] new port advice
2015-04-08 15:31 ` Nicholas Clifton
@ 2015-04-08 20:31 ` Peter Breuer
2015-04-09 13:54 ` Nicholas Clifton
0 siblings, 1 reply; 5+ messages in thread
From: Peter Breuer @ 2015-04-08 20:31 UTC (permalink / raw)
To: Nicholas Clifton; +Cc: binutils
Thanks Nick, that's a great pointer ..
On Wed, 08 Apr 2015 16:31:40 +0100
Nicholas Clifton <nickc@redhat.com> wrote:
> gas/config/tc-<your arch>.c
>
> You will probably want to update md_assemble() in that file, (or one
Unfortunately, the existing code there is not like MIPS, which has a
parse loop I could happily deal with. Instead the arch I am looking at
calls to CGEN, which loses me in a twisty maze :(. The md_assemble()
code does
gas_cgen_init_parse ();
insn.insn = XXX_or1k_cgen_assemble_insn(....);
gas_cgen_finish_insn(insn.insn, ...)
I can see the XXX_or1k_cgen_assemble_insn in opcodes/XXX-asm.c but
it calls to yet more generic code, which presumably works off the
XXX_cgen_insn_table array that I can see in opcodes/XXX-desc.c.
The entries are opaque to me. The "addi" entry says
/* addi $rD,$rA,$simm16 */
{
XXX_INSN_L_ADDI, "l-addi", "l.addi", 32, { 0, { { { load_of_flags, 0 } } } }
},
I think that must be parse info. So gas_cgen_finish_insn must do the
printout work.
Any idea how I can meddle with that? I can see the code in cgen.c, but
it's utterly opaque to me what it consults ...
Regards
Peter
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [gas] new port advice
2015-04-08 20:31 ` Peter Breuer
@ 2015-04-09 13:54 ` Nicholas Clifton
2015-04-13 23:03 ` Peter Breuer
0 siblings, 1 reply; 5+ messages in thread
From: Nicholas Clifton @ 2015-04-09 13:54 UTC (permalink / raw)
To: Peter.T.Breuer; +Cc: binutils
Hi Peter,
> Instead the arch I am looking at
> calls to CGEN, which loses me in a twisty maze :(.
Ah yes - that would be a problem. You may find that abandoning cgen and
starting from (almost) scratch is an easier way to go. Ie take an
existing non-cgen port, eg RX or ARM, and adapt that to your
architecture. It may take a bit more work initially, but in the long
run you may find it easier to mainatain.
Alternatively if you want to stick with cgen, read on...
> I can see the XXX_or1k_cgen_assemble_insn in opcodes/XXX-asm.c but
> it calls to yet more generic code, which presumably works off the
> XXX_cgen_insn_table array that I can see in opcodes/XXX-desc.c.
>
> The entries are opaque to me. The "addi" entry says
>
> /* addi $rD,$rA,$simm16 */
> {
> XXX_INSN_L_ADDI, "l-addi", "l.addi", 32, { 0, { { { load_of_flags, 0 } } } }
> },
Yeah, it is all table based and created by some Scheme scripts from data
in the cpu/ directory.
> Any idea how I can meddle with that? I can see the code in cgen.c, but
> it's utterly opaque to me what it consults ...
Take a look at cpu/or1korbis.cpu. It seems to me that you are going to
have to replace the definition of ADDI as a normal instruction with some
kind of macro instruction generating sequence. And if you can do that
then you are a better man than I am Gungha Din.
Cheers
Nick
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [gas] new port advice
2015-04-09 13:54 ` Nicholas Clifton
@ 2015-04-13 23:03 ` Peter Breuer
0 siblings, 0 replies; 5+ messages in thread
From: Peter Breuer @ 2015-04-13 23:03 UTC (permalink / raw)
To: Nicholas Clifton; +Cc: binutils
On Thu, 09 Apr 2015 14:54:20 +0100
Nicholas Clifton <nickc@redhat.com> wrote:
> Take a look at cpu/or1korbis.cpu. It seems to me that you are going
> to have to replace the definition of ADDI as a normal instruction
> with some kind of macro instruction generating sequence. And if you
> can do that then you are a better man than I am Gungha Din.
Gunga Din says it need not be done that way.
The structure of md_assemble in tc-XXX.c is
md_assemble(char *str) {
XXX_insn insn;
/*0*/ gas_cgen_init_parse();
/*1*/ insn = XXX_cgen_assemble_insn(.. str, ...);
/*2*/ gas_cgen_finish_insn (insn, 32, ...);
}
and *1* is a parse of the incoming ascii assembler line (str) to some
insn struct and *2* is a pretty print of the insn struct as machine
code.
So between *1* and *2* one gets the opportunity to do some rejigging
when the right sort of instruction turns up.
An addi is whapped into a new shape, for example, by rewriting every
field in sight in the insn struct to something that looks right for
what it should end up as. If it works, it works. Continue until it is
so.
The addi is prefixed by other instructions by putting between the
*1*/*2* pair another parse-print pair:
pre_insn1 = XXX_cgen_assemble_insn(... mystr1 ...);
gas_cgen_finish_insn(pre_insn1, 32, ...);
and repeat for as many prefix instructions as wanted.
The cute thing is that the target addi has already been parsed and that
grabs for the parser a label from the assembler file (if it had one) and
all the prefixes now get the same label, as the label is changed in the
parser's state only when a new label is met. That's the only
significant bit of statefulness I noticed in the parse. Thank goodness
it's simple - if it is.
So the XXX_cgen_assemble_insn call is pretty much independent (I
think the jargon is `re-entrant') each time, so one can call it as one
likes on the assembler strings one makes up any old way. And machine
code gets emitted from gas_cgen_finish_insn.
The horribleness is that I have no idea what fields of insn are really
significant either for the printer or for whatever the parser remembers
or might do next. Oh for a document. Still, it works, seemingly.
PTB
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2015-04-13 23:03 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-07 15:47 [gas] new port advice Peter Breuer
2015-04-08 15:31 ` Nicholas Clifton
2015-04-08 20:31 ` Peter Breuer
2015-04-09 13:54 ` Nicholas Clifton
2015-04-13 23:03 ` Peter Breuer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).