GCC POTATO-I 移植

移植GCC提供以下几个文件,其中有些是必须的而有些是可选的。
target-cpu.md  目标cpu描述文件
target-cpu.h  目标cpu头文件(可选)
target-cpu.c   目标cpu源文件,targe-cpu.md提供辅助函数

 

目标cpu描述文件target-cpu.md主要包括以下内容:
目标体系结构的寄存器描述
字长
端模式(Big-endian / Little-endian)
...
target-cpu.h
ABI 
 函数调用时栈的使用方式
 函数参数是通过寄存器还是栈进行传递
 ...
target-cpu.c
 对target-cpu.md提供辅助函数
 
 以上文件的具体内容参看《GCC Internals》文档
 
 target-cpu.md文件比较庞大,但对于成功编译GCC来说其内容并不需要如此之大。
 例如为了能够编译以下的简单C程序.md文件可以仅包含两个GCC内部虚拟机标准指令即可实现,它们是
 ‘jump’和‘ret',因为函数的编译需要跳转指令和返回指令;
 int main(void)
 {
  return 0;
 }
 .md文件内容大体如下:
 (define_insn "jump"
  [(set (pc) (label_ref (match_operand 0 "" "")))]
  ""
  "b%* %l0"
  [(set_attr "type" "uncond_branch")])
 
 define_insn("ret" ...)
 
为了能够编译C语言的其他语言结构如if-else, for, while等.md文件必须提供其他的GCC虚拟机标准指令集,
如为了实现if-else及for语句必须提供比较指令‘cmp'等等。在GCC文档中没有说明C语言语句与GCC虚拟机
标准指令集之间的严格对应关系。

.md文件的内容给人一种杂乱无章的感觉,且《GCC Internals》也没有对GCC内部虚拟机的指令集哪些是必须
在.md文件中提供也没有明确的解释,指令系统的描述又分define_insn和define_expand等两种模式更是让人
摸不着头脑。

GCC内部使用“模板匹配”的方法对.md文件中的虚拟机指令集进行匹配从而生成中间代码及目标体系结构汇编语言。
而“模板匹配”并不是匹配GCC虚拟机标准指令的名称,而是匹配指令集的格式。
例如
(define_insn "*movsi"
  [(set (match_operand:SI 0 "register_operand" "=r")
 (match_operand:SI 1 "register_operand" "r"))]
 
  "mov%? %0,%1"

  [(set_attr "type" "move")])
 
 在以上的指令模板中指令名称movsi在生成RTL时被忽略,GCC根据其内部规则生成寄存器间传送数据的RTX表达式,
 而该表达式的两个操作数分别为两个寄存器,在汇编代码生成阶段匹配RTX表达式的操作数和movsi指令模板的
 两个操作数类型(match_operand:SI 0 "register_operand"和 match_operand:SI 1; "register_operand"
 表示第一个操作数为Single Integer类型的寄存器,第二个操作数为Single Integer类型的寄存器),进而
 生成 mov r0, r1格式的汇编指令。
 
 以下模板描述了传送立即数到寄存器的指令模式
  (define_insn "*movsi"
  [(set (match_operand:SI 0 "register_operand" "=r")
 (match_operand:SI 1 "immidiate_operand" "i"))]
 
  "mov%? %0,%1"

  [(set_attr "type" "move")])
 
  以上两个指令模板虽然名称相同但不会冲突,这也说明了GCC对指令模板的使用是根据其操作数的格式而不是
  名称这一事实。