4

How is the C language portable to any instruction set (I mean for new architectures)? Do we have to write a new C compiler for each new architecture?

0

5 Answers 5

6

in general, every new architecture needs a new port of the C compiler (along with the rest of the C tool chain)

Usually this starts with the development of a 'cross compiler' on a known architecture to compile C for the new architecture.

(the compiler, itself, can be what is being compiled, from source, for the new architecture.)

even a related new architecture needs lots of updates to the compiler to take advantage of the new architecture. For instance taking a 8086 C compiler and modifying it for a 80486 architecture

the changes between the underlying hardware (8 bit, 16 bit, 32 bit, 64 bit, 128 bit, etc requires changes to the compiler to take advantage of the new architecture. Changes to the compiler, due to a different bus (ISA, s80, etc etc can be made to take advantage of the different bus capabilities, but is usually not a first consideration. A much more important consideration is: What instructions can the new CPU support and how is 'pipelining' handled and what ALU/etc units (and how many of each unit) are available in the new CPU.

6

How C language is portable to any instruction set (I mean for new architecture).

It is not, but C is portable to most reasonable instruction sets close to existing ones.

As an hypothetical counter-example, you might define a computer architecture using ternary (not binary) or decimal. Both did happen in the past (1960s: IBM/1620 was decimal, Russian Setun was ternary). For these machines a C [cross-] compiler is simply not possible. On past Lisp machines (or Smalltalk ones) or on Rekursiv or iAPX432 machines, C would be very difficult (nearly impossible) to port. The current SAFE Darpa project defines an architecture which is not C friendly.

In practice, availability of bytes (of 8 bits), byte addressing, Harvard or Von Neumann architecture is almost required for a reasonable C compiler. C -and a big lot of practical programs coded in C- could be ported to most 32 or 64 (or hypothetical 128) bits machines (but would be much more difficult to port to 24 bits or 48 bits machines, or to machines with 9-bits char and 36 bits words, even if that would be feasible in principle).

Of course, when you define a new architecture today (e.g. RISCV or MILL), you practically define it to be more or less C compatible (and close to some existing processor, often able to run some POSIX-like OS) and you design (and code, often by porting some existing compiler like GCC or Clang), a C cross-compiler for it. Otherwise, if your architecture is radically different, you need to think (and budget) the development of compilers and operating systems for it.

Also, you are not sure that a given program (e.g. the Linux kernel, or the Firefox browser) can be easily be ported to your new architecture.

Be aware that software portability is not a yes/no feature (think of endianness, data alignment, cache coherence on multi-core processors, implementation specific code, asm instructions, undefined behavior, availability of libraries, operating system API - Win API is very different from POSIX). The saying is there is no portable software, only software which has been ported to some particular computer. Even Linux distributions for x86-64 have various and different package managers, and to compile your same source code you could need different packages on different distributions. For instance RefPerSys is a free software -coded in C++17 and using Qt5- for Linux I am contributing to, but depends on various packages named differently (and in its commit e611de7f depends on the build automation tool omake 0.10.3 which might not be packaged on your distribution, but omake is GPLed free software)

Do we have to write again C compiler for new architecture?

Yes, and that could be a cross-compiler. Look inside the source code of GCC for various examples. Each of them could mean a year of full-time work.

1
  • 1
    "Also, you are not sure that a given program (e.g. the Linux kernel, or the Firefox browser) can be easily be ported to your new architecture." How so? What would make it that a C program would not work on a new architechture when compiled with a C compiler that targets this new architechture ?
    – Didier A.
    Jan 15, 2020 at 2:06
2

Yes. The instruction set is defined, machine code, an assembly language syntax is defined along with an assembler. Most likely a linker, and then you are ready for a port of the C compiler. And then you can start with bootloaders, operating systems etc (naturally after design verification or as part of it).

On rare occasions does anyone vary from this path, and as rare do they succeed. You can always port countless languages as well, but you wont get very far without an assembler and a C compiler for a general purpose processor.

If it is not a general purpose processor then an assembler may be all that is required.

1

We don't have to write a C Compiler for every new architecture. For example the Lisp Machine and the Java VM can do very well without a C compiler.

However, if you really want to, C is portable even to these architectures as they are Turing complete.

For the common, C-friendly architectures an often used approach is to start writing and using a C cross-compiler. If you then want to be independent of cross-compiling, you can cross-compile a C compiler and voila, you have a native C compiler on your new architecture.

3
  • How would you propose that software implementations of LispM and the JVM come to run on a new architecture?
    – Blrfl
    Jul 3, 2016 at 11:53
  • @Blrfl. That is a different question. On a "common" architecture, I would probably start porting a Compiler to it and continue from there. :)
    – Peter G.
    Jul 3, 2016 at 12:08
  • @Blrfl: You can write a LispM/JVM interpreter/bytecode transpiler in the machine code of that new architecture. It'll be very tedious, but it is not actually that difficult.
    – Lie Ryan
    Jan 15, 2020 at 23:55
1

If the capabilities of your new ISA are similar to existing ones, then you can save a lot of work. For example, you could add a new backend to LLVM and get many programming languages for free.

To do this, you would describe basic details of your ISA to the compiler (bit sizes of integers, pointers, floating point numbers). Your C code can then be compiled to some intermediate language containing things very similar to assembler, but ISA independent. You then have to write a backend that translates this intermediate language to your ISA.

By writing one backend, you get all programming languages supported by the frontends for free.

Now if your ISA is too different, like ternary, crazy word and pointer sizes and so on then you might have problems.

For more information, check this article by Chris Lattner: https://aosabook.org/en/llvm.html

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.