LLVM-IR(LLVM中間コード)用コンパイラの作り方 その11

前回の続き

配列変数の実装について、書くのを忘れていた。

10 DIM A(10)
みたいにTinyBasicで配列宣言をしたときに、LLVM-IRでそれに対応したコードを生成する。
通常の変数の場合は、最初に出現した時に生成するのだが、配列はDIM文で宣言が必要という仕様だ。

  %_A0 = alloca [11 x i32], align 4

というように11個の32bit整数のメモリ空間を割り当てる。
10個で無いのは、A(0)~A(10)まで11個だからだ。

20 A(1)=2
のような代入文は、

  store i32 1 , i32* %acc, align 4
  %1 = load i32* %acc, align 4
  store i32 2 , i32* %acc, align 4
  %2 = load i32* %acc, align 4
  %3 = getelementptr inbounds [11 x i32]* %_A0, i32 0, i32 %1
  store i32 %2, i32 * %3, align 4

と、このようにgetelementptrを使う。

30 PRINT A(1)+A(2)+A(3)
の場合は、

  store i32 1 , i32* %acc, align 4
  %10 = load i32* %acc, align 4
  %11 = getelementptr inbounds [11 x i32]* %_A0, i32 0, i32 %10
  %12 = load i32* %11, align 4
  store i32 %12, i32* %acc
  %13 = load i32* %acc, align 4
  store i32 2 , i32* %acc, align 4
  %14 = load i32* %acc, align 4
  %15 = getelementptr inbounds [11 x i32]* %_A0, i32 0, i32 %14
  %16 = load i32* %15, align 4
  store i32 %16, i32* %acc
  %17 = load i32* %acc, align 4
  %18 = add nsw i32 %13, %17
  store i32 %18, i32* %acc
  %19 = load i32* %acc, align 4
  store i32 3 , i32* %acc, align 4
  %20 = load i32* %acc, align 4
  %21 = getelementptr inbounds [11 x i32]* %_A0, i32 0, i32 %20
  %22 = load i32* %21, align 4
  store i32 %22, i32* %acc
  %23 = load i32* %acc, align 4
  %24 = add nsw i32 %19, %23
  store i32 %24, i32* %acc
  %25 = load i32* %acc, align 4
  %26 = call i32(i8*,...)* @printf(i8* getelementptr inbounds([4 x i8]* @.1, i32 0, i32 0), i32 %25) nounwind

となる。

これでもう一通りTinyBasicコンパイラのコード生成の中身の解説は終了してしまったかな。




コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

Time limit is exhausted. Please reload CAPTCHA.

83 − = 76