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?
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.
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. 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.
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.
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