コンパイラ作成(82) double型の複雑な四則演算
今回の目標
前回に続き四則演算。
// double型 int main() { printf("%f\n", 2.0 + 5.0 / 2.0); }
前回対応できなかった複雑な式。
コード生成部
codegen_elsの括弧の処理部と関数呼出の処理部を修正。
def codegen_els(op, operand, type_l) ostr = mnemonic op, type_l # 右被演算子を評価 type_r = "int" if operand.kind_of?(Array) then if operand[0].size == 2 && operand[0].kind == TK::ID && operand[1].str == "()" then if type_l == "double" then codegen " sub rsp, 16" codegen " movsd [rsp], xmm8" type_r = codegen_func operand codegen " movsd xmm9, xmm8" codegen " movsd xmm8, [rsp]" codegen " add rsp, 16" str = "xmm9" else codegen " sub rsp, 8" codegen " push rax" type_r = codegen_func operand codegen " mov r10d, eax" codegen " pop rax" codegen " add rsp, 8" str = "r10d" end else if type_l == "double" then codegen " sub rsp, 16" codegen " movsd [rsp], xmm8" type_r = codegen_el operand codegen " movsd xmm9, xmm8" codegen " movsd xmm8, [rsp]" codegen " add rsp, 16" str = "xmm9" else codegen " sub rsp, 8" codegen " push rax" type_r = codegen_el operand codegen " mov r10d, eax" codegen " pop rax" codegen " add rsp, 8" str = "r10d" end end
レジスタの退避処理だけど、xmmレジスタはpush/popできないんだね。仕方ないんでrsp弄った後にmovsdするようにしたよ。
動作テスト
~/myc$ myc p10.myc ~/myc$ ./p10 4.500000 ~/myc$
お、ちゃんと計算できるようになったよ。今回ので式の途中での関数呼出もできるようになったはずだよなあ。ああ、でももう一回処理を見直した方が良いかな。現状でどこまで実装できたのか分からなくなってきたよ。拙い状況だよ。うーむ。