4

I am using gcc to compile a set of c codes. And my question is: can I tell gcc not to generate some specific instructions?

e.g. I don't want gcc to generate MUL instruction, how should I do?

I'm working on self implemented MIPS cpu and related codes, and for some reasons, I don't want gcc to generate some weird instructions that I've not implemented. It seems that I need to hack the gcc a little bit.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • 5
    If it was an instruction from say arm5 that didn't exist in arm4, then a suitable -march would work. But for arbitrary instructions, you'll need to modify gcc... – Marc Glisse Jan 08 '18 at 11:20
  • 2
    gcc or any compiler doesnt generically work like that. some instructions for some targets based on architecture. Otherwise gcc is open source and you can modify your version. – old_timer Jan 08 '18 at 12:58
  • 1
    are you asking about x86 or arm you have both tagged? – old_timer Jan 08 '18 at 12:58
  • You need to precise by what set of instruction gcc will replace `MUL`. Normaly if you compile under arm architecture that doesn't handle `MUL` instruction, gcc should throw you an undefined reference. To avoid that, you can find on internet arm algorithm that replace the multiplication, modulo and division operation. – Brighter side Jan 08 '18 at 14:04
  • Guess this is an [XY-problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) and your real question might be [How can I multiply and divide using only bit shifting and adding?](https://stackoverflow.com/questions/2776211/how-can-i-multiply-and-divide-using-only-bit-shifting-and-adding) – Bo Persson Jan 08 '18 at 14:15
  • 1
    Actually, the thing is: I'm working on self implemented `MIPS` cpu and related codes, and for some reasons, I don't want `gcc` to generate some weird instructions that I've not implemented. It seems that I need to hack the `gcc` a little bit... – TheNetAdmin Jan 08 '18 at 14:30
  • ouch... then your question is quite valid, but the answer is probably not very simple one (and too broad for SO?). Basically you will need to write new "back-end" or how the gcc folk calls the machine code generator parts. I have no idea how difficult that is (although I know it's relatively the [second] easiest part of gcc to write (parser is probably even simpler, depends on CPU you want generate machine code for, if the CPU supports pretty much everything what the internal code representation needs with enough registers, it can be translated 1:1 to machine code, limited CPU is harder)). – Ped7g Jan 08 '18 at 18:28
  • And actually, as you are creating crippled MIPS, you can very likely start with regular MIPS back-end, and just write replacements for instructions you don't have yet. But I never actually checked gcc sources, so I may be quite wrong what is simpler approach and where to start. You may also want to check ARM/x86 back-ends to see how they solve the missing instructions on particular step of architecture, like ARMv4 vs ARMv5, etc. Whether they have almost full code generator for each architecture, or reuse most of it and just emit replacement code for missing instructions. – Ped7g Jan 08 '18 at 18:31
  • 2
    It may be as easy as removing a define_insn (or define_expand or...) block in gcc/config/mips/*.md. – Marc Glisse Jan 08 '18 at 23:24
  • probably it'll be easier on llvm – phuclv Jan 09 '18 at 11:07
  • 1
    [How to create a C compiler for custom CPU?](https://stackoverflow.com/q/8696229/995714), [How to write your own code generator backend for gcc?](https://stackoverflow.com/q/10617215/995714) – phuclv Jan 09 '18 at 11:13
  • 2
    For the specific case of MUL you can force `ISA_HAS_R6MUL` to be 0 in `config/mips/mips.h`, but in the general case. as Marc Gilisse said, disabling the `define_insn` and `define_expand` statements that that generate a given instruction will prevent that instruction from being emitted. Instead GCC will either emit some other instruction(s), emit a library call, or crash with a fatal error. – Ross Ridge Jan 09 '18 at 19:31

1 Answers1

1

Based on Krister Walfridsson's blog, the way to do it could be:

  • Add an command line option to the machine.opt file, so to create a global variable.
  • Find the instruction node in machine.md or other files, that emits the instruction you want to disable. Change the condition to be on the new variable you'v added. When the condition is not met, gcc would emit a call to a function that you'll supply in your .c file or lib file.

As a simpler example, take a look at the ft32 architecture directory. It creates an global variable NODIV based on a -mnodiv command line option. The instruction node in the ft32.md file contains:

(define_insn "divsi3"
  [(set (match_operand:SI 0 "register_operand" "=r,r")
          (div:SI
           (match_operand:SI 1 "register_operand" "r,r")
           (match_operand:SI 2 "ft32_rimm_operand" "r,KA")))]
  "!TARGET_NODIV"
  "div.l  %0,%1,%2")

In this ft32 case, when the variable is not set, gcc emits div.l assembly code. When it is set, it would make a call to a function named __divsi3.

Though I have not tried this out. Will update with exact information when I get a chance to try it out.

minghua
  • 5,981
  • 6
  • 45
  • 71