Linux MIPS Architecture development
 help / color / mirror / Atom feed
* Assembly macro with parameters
@ 2005-04-07 17:53 Fabrizio Fazzino
  2005-04-07 18:25 ` Ralf Baechle
  0 siblings, 1 reply; 11+ messages in thread
From: Fabrizio Fazzino @ 2005-04-07 17:53 UTC (permalink / raw)
  To: linux-mips

Hi all,
I'm working to an hardware extension of the MIPS32 instruction set
and I need to convert my new instruction into an existing opcode
to make it possible for the normal GCC to correctly compile the code.

Just to be clear, to obtain my new FZMIN instruction like

	FZMIN $rd, $rs, $rt

I have to convert it into

	LWC1 $rt, rd<<11 ($rs)

that is an existing (in some cases unused) opcode.

I'm currently using hardcoded values for the parameters, so
fzmin(10,8,9) will be transformed into
	asm("lwc1 $9, 10<<11($8)" : : : "$10");

It works, but I need a way to set the values of the parameters
at runtime; so I've tried the following macro:

	#define fzmin(rd, rs, rt) asm("lwc1 $rt, rd<<11($rs)");

As you can imagine I'm not an expert of MIPS Assembly macros:
what I've written does NOT work since the values of rd,rs,rt
are NOT substituted inside the asm string.

Is there any way to do what I need? I would appreciate your
help very much.

Cheers,
	Fabrizio


-- 
============================================
    Fabrizio Fazzino - fabrizio@fazzino.it
      Fazzino.IT - http://www.fazzino.it
============================================

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Assembly macro with parameters
  2005-04-07 17:53 Assembly macro with parameters Fabrizio Fazzino
@ 2005-04-07 18:25 ` Ralf Baechle
  2005-04-08 16:47   ` Fabrizio Fazzino
  0 siblings, 1 reply; 11+ messages in thread
From: Ralf Baechle @ 2005-04-07 18:25 UTC (permalink / raw)
  To: Fabrizio Fazzino; +Cc: linux-mips

On Thu, Apr 07, 2005 at 07:53:49PM +0200, Fabrizio Fazzino wrote:

> Hi all,
> I'm working to an hardware extension of the MIPS32 instruction set
> and I need to convert my new instruction into an existing opcode
> to make it possible for the normal GCC to correctly compile the code.
> 
> Just to be clear, to obtain my new FZMIN instruction like
> 
> 	FZMIN $rd, $rs, $rt
> 
> I have to convert it into
> 
> 	LWC1 $rt, rd<<11 ($rs)
> 
> that is an existing (in some cases unused) opcode.
> 
> I'm currently using hardcoded values for the parameters, so
> fzmin(10,8,9) will be transformed into
> 	asm("lwc1 $9, 10<<11($8)" : : : "$10");
> 
> It works, but I need a way to set the values of the parameters
> at runtime; so I've tried the following macro:
> 
> 	#define fzmin(rd, rs, rt) asm("lwc1 $rt, rd<<11($rs)");

Which will leave the assembler entirely unimpressed ;-)

> As you can imagine I'm not an expert of MIPS Assembly macros:
> what I've written does NOT work since the values of rd,rs,rt
> are NOT substituted inside the asm string.
> 
> Is there any way to do what I need? I would appreciate your
> help very much.

Unless you only have a few instructions and are going for a quick hack
I really suggest to add proper support for these instructions to binutils.
Having working support in as, gdb, objdump will make your life so much
easier.

  Ralf

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Assembly macro with parameters
  2005-04-07 18:25 ` Ralf Baechle
@ 2005-04-08 16:47   ` Fabrizio Fazzino
  2005-04-08 16:57     ` Daniel Jacobowitz
  0 siblings, 1 reply; 11+ messages in thread
From: Fabrizio Fazzino @ 2005-04-08 16:47 UTC (permalink / raw)
  To: linux-mips

Ralf Baechle wrote:
> Fabrizio Fazzino wrote:
> 
>>It works, but I need a way to set the values of the parameters
>>at runtime; so I've tried the following macro:
>>
>>	#define fzmin(rd, rs, rt) asm("lwc1 $rt, rd<<11($rs)");
> 
> Which will leave the assembler entirely unimpressed ;-)

I thought that the compiler was able to substitute also the
values inside strings... Is there any way to force it to do so?

> Unless you only have a few instructions and are going for a quick hack
> I really suggest to add proper support for these instructions to binutils.
> Having working support in as, gdb, objdump will make your life so much
> easier.

The processor I'm designing probably will not be implemented in
any way (we just have to simulate the VHDL hardware description),
so we just need a quick-and-dirty way to make the opcode
conversion.

	Fabrizio


-- 
============================================
    Fabrizio Fazzino - fabrizio@fazzino.it
      Fazzino.IT - http://www.fazzino.it
============================================

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Assembly macro with parameters
  2005-04-08 16:47   ` Fabrizio Fazzino
@ 2005-04-08 16:57     ` Daniel Jacobowitz
  2005-06-30 17:20       ` Fabrizio Fazzino
  0 siblings, 1 reply; 11+ messages in thread
From: Daniel Jacobowitz @ 2005-04-08 16:57 UTC (permalink / raw)
  To: Fabrizio Fazzino; +Cc: linux-mips

On Fri, Apr 08, 2005 at 06:47:58PM +0200, Fabrizio Fazzino wrote:
> Ralf Baechle wrote:
> >Fabrizio Fazzino wrote:
> >
> >>It works, but I need a way to set the values of the parameters
> >>at runtime; so I've tried the following macro:
> >>
> >>	#define fzmin(rd, rs, rt) asm("lwc1 $rt, rd<<11($rs)");
> >
> >Which will leave the assembler entirely unimpressed ;-)
> 
> I thought that the compiler was able to substitute also the
> values inside strings... Is there any way to force it to do so?
> 
> >Unless you only have a few instructions and are going for a quick hack
> >I really suggest to add proper support for these instructions to binutils.
> >Having working support in as, gdb, objdump will make your life so much
> >easier.
> 
> The processor I'm designing probably will not be implemented in
> any way (we just have to simulate the VHDL hardware description),
> so we just need a quick-and-dirty way to make the opcode
> conversion.

You should probably be using .word then, and generating the instruction
completely by hand.

-- 
Daniel Jacobowitz
CodeSourcery, LLC

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Assembly macro with parameters
  2005-04-08 16:57     ` Daniel Jacobowitz
@ 2005-06-30 17:20       ` Fabrizio Fazzino
  2005-06-30 17:32         ` David Daney
  2005-07-01  8:38         ` Maciej W. Rozycki
  0 siblings, 2 replies; 11+ messages in thread
From: Fabrizio Fazzino @ 2005-06-30 17:20 UTC (permalink / raw)
  To: linux-mips

After three months I still have the same problem...

Suppose I want to generate my own opcode, let's say 0xC4000000,
inside a C program. Suppose this value is NOT a constant in
the macro I want to write since it will contain three
variable fields for the rd,rs,rt registers, so I need to calculate
the opcode at least at compilation time (at runtime is NOT
required).

Daniel suggested using .word and writing the function by hand,
but which is the syntax I have to use?

#define myopcode(rs,rt,rd) { \
   int opcode_number = 0xC4000000 | (rs<<21) | (rt<<16) | (rd<<11); \
   char opcode_string[20]; \
   sprintf(opcode_string, ".word 0x%X", opcode_number); \
   asm(opcode_string); \
}

This doesn't work since "argument of 'asm' is not a constant string"...
Furthermore I do NOT have the possibility to link the string library
so I should find another solution.

Is there any common solution to write an instruction "completely
by hand" ?

Many thanks in advance,

	Fabrizio Fazzino



Daniel Jacobowitz wrote:
> On Fri, Apr 08, 2005 at 06:47:58PM +0200, Fabrizio Fazzino wrote:
> 
>>Ralf Baechle wrote:
>>
>>>Fabrizio Fazzino wrote:
>>>
>>>>It works, but I need a way to set the values of the parameters
>>>>at runtime; so I've tried the following macro:
>>>>
>>>>	#define fzmin(rd, rs, rt) asm("lwc1 $rt, rd<<11($rs)");
>>>
>>>Which will leave the assembler entirely unimpressed ;-)
>>
>>I thought that the compiler was able to substitute also the
>>values inside strings... Is there any way to force it to do so?
> 
> You should probably be using .word then, and generating the instruction
> completely by hand.
> 


-- 
============================================
    Fabrizio Fazzino - fabrizio@fazzino.it
      Fazzino.IT - http://www.fazzino.it
============================================

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Assembly macro with parameters
  2005-06-30 17:20       ` Fabrizio Fazzino
@ 2005-06-30 17:32         ` David Daney
  2005-07-01  8:38         ` Maciej W. Rozycki
  1 sibling, 0 replies; 11+ messages in thread
From: David Daney @ 2005-06-30 17:32 UTC (permalink / raw)
  To: Fabrizio Fazzino; +Cc: linux-mips

Fabrizio Fazzino wrote:
> After three months I still have the same problem...
> 
> Suppose I want to generate my own opcode, let's say 0xC4000000,
> inside a C program. Suppose this value is NOT a constant in
> the macro I want to write since it will contain three
> variable fields for the rd,rs,rt registers, so I need to calculate
> the opcode at least at compilation time (at runtime is NOT
> required).
> 
> Daniel suggested using .word and writing the function by hand,
> but which is the syntax I have to use?
> 
> #define myopcode(rs,rt,rd) { \
>   int opcode_number = 0xC4000000 | (rs<<21) | (rt<<16) | (rd<<11); \
>   char opcode_string[20]; \
>   sprintf(opcode_string, ".word 0x%X", opcode_number); \
>   asm(opcode_string); \
> }
> 

The arguments to the asm() statement are strings not char*.  They are 
evaluated at compile time not run time.

You will probably have to use the C preprocessor stringification and 
concatination operators ('#' and '##').

David Daney

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Assembly macro with parameters
  2005-06-30 17:20       ` Fabrizio Fazzino
  2005-06-30 17:32         ` David Daney
@ 2005-07-01  8:38         ` Maciej W. Rozycki
  2005-07-03 10:31           ` Fabrizio Fazzino
  1 sibling, 1 reply; 11+ messages in thread
From: Maciej W. Rozycki @ 2005-07-01  8:38 UTC (permalink / raw)
  To: Fabrizio Fazzino; +Cc: linux-mips

On Thu, 30 Jun 2005, Fabrizio Fazzino wrote:

> Daniel suggested using .word and writing the function by hand,
> but which is the syntax I have to use?
> 
> #define myopcode(rs,rt,rd) { \
> int opcode_number = 0xC4000000 | (rs<<21) | (rt<<16) | (rd<<11); \
> char opcode_string[20]; \
> sprintf(opcode_string, ".word 0x%X", opcode_number); \
> asm(opcode_string); \
> }

 This is untested, but it should be a reasonable starting point:

#define myopcode(rs,rt,rd) do { \
	int opcode_number = 0xC4000000 | (rs<<21) | (rt<<16) | (rd<<11); \
	asm(".word %0" : : "i" (opcode_number)); \
} while (0)

But you may want to add code to tell GCC that these registers are used and 
how, because otherwise you may have little use of your macro.  You'll 
probably have to investigate the explicit register variable GCC feature 
and cpp stringification.  It should be straightforward though rather 
boring, so I'm leaving it as an exercise.

  Maciej

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Assembly macro with parameters
  2005-07-01  8:38         ` Maciej W. Rozycki
@ 2005-07-03 10:31           ` Fabrizio Fazzino
  2005-07-04  7:40             ` Geert Uytterhoeven
  2005-07-04 12:12             ` Maciej W. Rozycki
  0 siblings, 2 replies; 11+ messages in thread
From: Fabrizio Fazzino @ 2005-07-03 10:31 UTC (permalink / raw)
  To: linux-mips

Many thanks Maciej and David,
during these days I've learned a lot about stringification, a feature
that I had never used before.

In any case I didn't have to use this feature... I was just missing the
fact that the opcode evaluation didn't have to happen by declaring an
int variable (in this case the value is computed at runtime) but by the
preprocessor, so I solved my problem this way:

#define NEWOPCODE(base,rd,rs,rt) (base|(rs<<21)|(rt<<16)|(rd<<11))
#define myopcode(rd,rs,rt) asm(".long %0" : : "i" (NEWOPCODE(0xC4000000,rd,rs,rt)))

and then I call it simply as myopcode(10,8,9).

By the way, is there any quick way of writing a setreg(reg_num,reg_val)
C macro to set the value of a register?
And another one to read the value like a reg2var(reg_num,&result) to put
the value of a register inside my own C variable?
I have written my own versions for both but they have a 32-case switch
statement inside so they are not so efficient...

In any case thanks a lot for your suggestions, I've put acknowledgments
to macro@linux-mips.org inside my code!

	Fabrizio


David Daney wrote:
> 
> The arguments to the asm() statement are strings not char*.  They are evaluated at compile time not run time.
> 
> You will probably have to use the C preprocessor stringification and concatination operators ('#' and '##').
> 
> David Daney
> 

Maciej W. Rozycki wrote:
> 
>  This is untested, but it should be a reasonable starting point:
> 
> #define myopcode(rs,rt,rd) do { \
> 	int opcode_number = 0xC4000000 | (rs<<21) | (rt<<16) | (rd<<11); \
> 	asm(".word %0" : : "i" (opcode_number)); \
> } while (0)
> 
> But you may want to add code to tell GCC that these registers are used and 
> how, because otherwise you may have little use of your macro.  You'll 
> probably have to investigate the explicit register variable GCC feature 
> and cpp stringification.  It should be straightforward though rather 
> boring, so I'm leaving it as an exercise.
> 
>   Maciej
> 


-- 
============================================
    Fabrizio Fazzino - fabrizio@fazzino.it
      Fazzino.IT - http://www.fazzino.it
============================================

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Assembly macro with parameters
  2005-07-03 10:31           ` Fabrizio Fazzino
@ 2005-07-04  7:40             ` Geert Uytterhoeven
  2005-07-04 12:12             ` Maciej W. Rozycki
  1 sibling, 0 replies; 11+ messages in thread
From: Geert Uytterhoeven @ 2005-07-04  7:40 UTC (permalink / raw)
  To: Fabrizio Fazzino; +Cc: Linux/MIPS Development

On Sun, 3 Jul 2005, Fabrizio Fazzino wrote:
> In any case I didn't have to use this feature... I was just missing the
> fact that the opcode evaluation didn't have to happen by declaring an
> int variable (in this case the value is computed at runtime) but by the
> preprocessor, so I solved my problem this way:
> 
> #define NEWOPCODE(base,rd,rs,rt) (base|(rs<<21)|(rt<<16)|(rd<<11))
> #define myopcode(rd,rs,rt) asm(".long %0" : : "i"
> (NEWOPCODE(0xC4000000,rd,rs,rt)))
> 
> and then I call it simply as myopcode(10,8,9).
> 
> By the way, is there any quick way of writing a setreg(reg_num,reg_val)
> C macro to set the value of a register?
> And another one to read the value like a reg2var(reg_num,&result) to put
> the value of a register inside my own C variable?
> I have written my own versions for both but they have a 32-case switch
> statement inside so they are not so efficient...

As long as all arguments are constant and thus known at compile time. the
compiler will optimize away the switch completely (cfr. all those
{put,get}_user() routines).

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Assembly macro with parameters
  2005-07-03 10:31           ` Fabrizio Fazzino
  2005-07-04  7:40             ` Geert Uytterhoeven
@ 2005-07-04 12:12             ` Maciej W. Rozycki
  2005-07-09  7:22               ` Fabrizio Fazzino
  1 sibling, 1 reply; 11+ messages in thread
From: Maciej W. Rozycki @ 2005-07-04 12:12 UTC (permalink / raw)
  To: Fabrizio Fazzino; +Cc: linux-mips

On Sun, 3 Jul 2005, Fabrizio Fazzino wrote:

> By the way, is there any quick way of writing a setreg(reg_num,reg_val)
> C macro to set the value of a register?

 It would make no sense as GCC would still be free to use this register
for something else, therefore either destroying your "explicitly" assigned 
data or getting data already there destroyed.  You are really after asm 
constraints and explicit register variables as outlined in my previous 
response.  See GCC documentation for how to make use of these.

 BTW, how about adding support for opcodes you are interested in to 
binutils instead?  It would make interfacing them to GCC much easier.

  Maciej

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: Assembly macro with parameters
  2005-07-04 12:12             ` Maciej W. Rozycki
@ 2005-07-09  7:22               ` Fabrizio Fazzino
  0 siblings, 0 replies; 11+ messages in thread
From: Fabrizio Fazzino @ 2005-07-09  7:22 UTC (permalink / raw)
  To: linux-mips

Maciej W. Rozycki wrote:
> Fabrizio Fazzino wrote:
> 
>>By the way, is there any quick way of writing a setreg(reg_num,reg_val)
>>C macro to set the value of a register?

Hi guys,
just to let you know that I solved my problem this way:

    // Set a register to the desired value
    #define setreg(regnum,value) asm("move $" #regnum ", %0" : : "r"(value) : "$" #regnum)

    // Move the content of a register to the desired variable
    #define reg2var(regnum,var) asm("sw $" #regnum ", %0" : "=m"(*var) : : "memory")

>  BTW, how about adding support for opcodes you are interested in to 
> binutils instead?  It would make interfacing them to GCC much easier.

The CPU I'm working on will never "exist"... I'm just simulating it
as VHDL code, so I just needed a quick-and-dirty way of generating
inside my very short test programs the new opcodes added as an extension.

Thanks to all for your precious support!

Cheers and regards,

         Fabrizio


-- 
============================================
    Fabrizio Fazzino - fabrizio@fazzino.it
      Fazzino.IT - http://www.fazzino.it
============================================

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2005-07-09  7:21 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-04-07 17:53 Assembly macro with parameters Fabrizio Fazzino
2005-04-07 18:25 ` Ralf Baechle
2005-04-08 16:47   ` Fabrizio Fazzino
2005-04-08 16:57     ` Daniel Jacobowitz
2005-06-30 17:20       ` Fabrizio Fazzino
2005-06-30 17:32         ` David Daney
2005-07-01  8:38         ` Maciej W. Rozycki
2005-07-03 10:31           ` Fabrizio Fazzino
2005-07-04  7:40             ` Geert Uytterhoeven
2005-07-04 12:12             ` Maciej W. Rozycki
2005-07-09  7:22               ` Fabrizio Fazzino

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox