Do you need to take account of the different processors and their instructions when writing a compiler? Have instructions been standardised? Or what tools and techniques are available to assist with this? E.g. Ignoring machine instructions that are specific to a certain processor model.
-
2Maybe you have heard of LLVM?– rwongOct 7, 2012 at 8:32
-
@rwong no I haven't - I know very little about compilers. Thanks for pointing me in the right direction and I'll read through the site (and try working with clang vs gcc) but it would be really useful if you could explain what it is as an answer just in case someday that link breaks– br3w5Oct 7, 2012 at 8:35
-
1Java springs to mind, of course, but there are many other systems like that. E.G. UCSD Pascal, which was pretty decent for its time (1978).– Mr ListerOct 7, 2012 at 8:53
-
1llvm, java, pascal, python, etc have some flavor of common bytecode which is itself an instruction set (they dont share each one has its own different one). Then for each cpu type you need to translate/simulate the bytecode in native cpu instructions. For each supported cpu you have to do this work. for llvm there is a bytecode to native backend for each processor target, for java there is a jvm for each target (and often each operating system for each target), etc. so no there really isnt a common instruction set, they have always been very similar but not interchangable.– old_timerNov 1, 2012 at 19:12
-
What do you mean with "model of cpu"? Do you mean the difference between an ARM and an x86 processor, processors with very different architecture. Or do you mean different "models" of processors within same family? Like: an old pentium processor vs a celeron. The answer will be different.– Pieter BOct 1, 2015 at 9:13
2 Answers
No, instruction sets aren't "standardized" in a way that you could produce assembly that's fit for – or is simply mappable to – ARM, x86, PPC, MIPS, Itanium, Sparc, ... (and their variants).
Native code compilers are pretty complex beasts. Not all the work they do is processor-specific. All the lexing/parsing is language-dependent but not chip-related. Some optimization passes are also hardware-independent, but possibly not all – e.g. the right code size v.s. raw speed tradeoffs might depend on the target.
At some point, if you're producing native code, you'll need to know the details of the chip you're targeting. You need to be aware of their "quirks" (memory coherency properties for instance) and complete instruction sets to produce an instruction stream that is both correct and reasonably efficient.
Even if you restrict yourself to one instruction set (say x86_64), different brands of chips have different extensions that need to be considered. Different models of the same brand also have instruction set differences (new features added, sometimes old features removed). Sticking with the "lowest common denominator" could work, but you'll be missing out on a lot of stuff.
Does that mean the you do a complete rewrite of the compiler for every new instruction set or extension that hits the market? Of course not. Those are incremental changes, sometimes only to "machine description files" or whatever the compiler uses to model the target instruction set.
But introducing a new ISA altogether is not a trivial task and requires detailed knowledge of the target.
If you're setting out to build a compiler yourself, do have a look at LLVM. Chances are you use it for the "emitting native code" part at least, whatever language it is you're trying to compile.
The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
A compiler is usually composed of many parts. Generating the actual code is just one part, and a small one. So, to make a compiler for a new processor, you only need to make small changes to an old one.
Also, processors come in families. When (for example) Intel releases a new processor, it does everything the old processor does, and more. This means that you can continue to use the existing compiler. It will make programs that work on the new processor. They will not use the new instructions that is offered, but they will still work.
For example, rather old compilers will only produce 32-bit programs. The programs still run on new 64-bit computers, but they do not run well.
You probably want a new compiler to truely take advantage of the new chip, but it isn't necessary.