GCC移植--后端流程

时间:2023-01-06 03:01:39

GCC移植--后端流程
(自已小结备忘)
GCC前端生成的中间代码是若干RTL,每条RTL的名字是MOV,ADD,JMP等,后端工作的每遍会遍历这些RTL。
一 首先找标准名字的RTL。对每条RTL,如果它的名字是标准的MOV,ADD等,则会匹配相应的EXPAND或INSN模板。
1 当匹配了EXPAND模板时,先执行其中的C语句(参数可能是每个OPERAND,机器模式等)。在这些C语句中,可以调用如下函数等:
 force_reg:生成一条将指定RTX装入伪寄存器的RTX并返回。
 gen_reg_rtx:新分配一个伪寄存器的RTX并返回。
 
 emit_insn:生成一条INSN,加到RTL链表的尾部。
 emit_move_insn(operand0, operand1):生成将operand1 MOV到operand0的RTL,加入到RTL链表的尾部。
 gen_x:如gen_symbolic_address_load,x是INSN模板的名字,该函数是GCC编译过程中生成的,在insn-emit.c文件中:
  例如对以下INSN模板:
  (define_insn "symbolic_address_load"
   [(set (match_operand:SI 0 "zero_register_operand" "=b")
      (match_operand:SI 1 "symbolic_operand" "S"))
   ]
   ""
   "MOVI //t #%s1 //t-L"
  )
  GCC编译时会在insn-emit.c文件中生成对应函数:
  rtx
  gen_symbolic_address_load (rtx operand0 ATTRIBUTE_UNUSED,
   rtx operand1 ATTRIBUTE_UNUSED)
  {
    return gen_rtx_SET (VOIDmode,
   operand0,
   operand1);
  }
  它的参数是该INSN的每个要匹配的OPERAND,函数体会根据该INSN要做的工作,去调用相应的RTL生成函数,这导致在匹配RTL阶段可以调用INSN模板去生成新的RTL。
 ?在EXPAND模板的C语句中,如果调用了DONE或FAILED,则执行完后结束,不再匹配该EXPAND模板,否则去匹配。
2 ?当匹配了INSN模板x时,直接调用对应的gen_x函数,其它与EXPAND模板类似。
二 每一遍都遍历所有RTL,包括上一遍新生成的,直到不再生成新的RTL。
三 优化这些RTL。
四 寄存器分配(reload),包括局部寄存器分配(对应.lreg文件),和全局寄存器分配(对应.greg文件)。任务是对每条RTL中的伪寄存器,将其替换为适当的硬件寄存器。
五 输出汇编指令。再次遍历RTL链表,对每条RTL,寻找其匹配的INSN模板,找到后,按该INSN汇编模板的格式,输出相应的汇编指令。