コンパイラ作成(84) double型の等価演算子

今回の目標

等価演算子をサポートするよ。

// double型の乱数
int main()
{
    double x;
    x = 1.5;
    if( x == 1.5 )
        printf("true\n");
    else
        printf("false\n");
    x = 1.0;
    if( x == 1.5 )
        printf("true\n");
    else
        printf("false\n");
}
コード生成部

まずはここを修正。

  # ニーモニック
  def mnemonic(op, type)
    if type == "double" then
      if op.str == "+" then
        return "addsd "
      elsif op.str == "-" then
        return "subsd "
      elsif op.str == "*" then
        return "mulsd "
      elsif op.str == "/" then
        return "divsd "
      elsif op.str == "%" then
        return "divsd "
      elsif op.str == "==" then
        return "ucomisd"
      elsif op.str == "!=" then
        return "cmp "
      elsif op.str == "<" || op.str == "<" || op.str == ">" || op.str == "<=" || op.str == ">=" then
        return "cmp "
      else
        perror "unknown operator \"" + op.str + "\""
      end
    else
      if op.str == "+" then
        return "add "
      elsif op.str == "-" then
        return "sub "
      elsif op.str == "*" then
        return "imul"
      elsif op.str == "/" then
        return "idiv"
      elsif op.str == "%" then
        return "idiv"
      elsif op.str == "==" then
        return "cmp "
      elsif op.str == "!=" then
        return "cmp "
      elsif op.str == "<" || op.str == "<" || op.str == ">" || op.str == "<=" || op.str == ">=" then
        return "cmp "
      else
        perror "unknown operator \"" + op.str + "\""
      end
    end
  end

ucomisdってので比較できるみたいだ。次はcodegen_elsの等価演算子の処理のところ。

    # 左被演算子と右被演算子とで計算
    if op.str == "==" then
      codegen "  " + ostr + " #{reg}, " + str
      if type_l == "double" then
        codegen "  sete  al"
        codegen "  setnp r10b"
        codegen "  and   al, r10b"
        codegen "  and   eax, 1"
        type_l = "int"
      else
        codegen "  sete al"
        codegen "  and  eax, 1"
      end

clang先輩の出力を参考にしたんだけど、なぜこうなってるのか理解できないよ。この辺の知識が不足してるなあ。

動作テスト
~/myc$ ./p15
true
false
~/myc$

ちゃんと動いてるね。今回はあんまり時間取れなかったんでちゃんと理解することなく、clang先輩の真似っこしちゃったよ。時間ができたらもう一度見直さないと駄目だな。今回は等価演算子一個しか追加できなかったけど、次回は頑張って残りの比較演算子全部追加したいなあ。