マンデルブロを動かすRP2350コードを出力
https://gyazo.com/59a4f5d9c9201b4d6f96a887b3d2c8be
ちょっと修正したら動いた。
code:diff
diff --git a/Makefile b/Makefile
index 453e68b..de71cd1 100644
--- a/Makefile
+++ b/Makefile
@@ -86,6 +86,19 @@ sample/%.res: sample/%.elf
-D logfile.txt \
-kernel $<
+shootout/%.s: $(RESULT) shootout/%.ml
+ ./$(RESULT) shootout/$*
+shootout/%.elf: shootout/%.s startup.c stub.c libmincaml.S linker.ld
+ $(TGT_CC) $(TGT_CFLAGS) $(TGT_LDFLAGS) -o $@ $< startup.c stub.c libmincaml.S
+shootout/%.res: shootout/%.elf
+ qemu-system-arm \
+ -machine mps2-an505 \
+ -cpu cortex-m33 \
+ -m 16M \
+ -nographic \
+ -monitor none \
+ -kernel $<
+
.PRECIOUS: test/%.s test/% test/%.res test/%.ans test/%.cmp
TRASH = $(TESTS:%=test/%.s) $(TESTS:%=test/%) $(TESTS:%=test/%.res) $(TESTS:%=test/%.ans) $(TESTS:%=test/%.cmp)
diff --git a/RP2350/emit.ml b/RP2350/emit.ml
index b397ccb..69fcc24 100644
--- a/RP2350/emit.ml
+++ b/RP2350/emit.ml
@@ -84,10 +84,10 @@ and g' oc = function (* 各命令のアセンブリ生成 (caml2html: emit_gprim
| NonTail(x), FMr(y) when x = y -> ()
| NonTail(x), FMr(y) -> Printf.fprintf oc "\tfmr\t%s, %s\n" (reg x) (reg y)
| NonTail(x), FNeg(y) -> Printf.fprintf oc "\tfneg\t%s, %s\n" (reg x) (reg y)
- | NonTail(x), FAdd(y, z) -> Printf.fprintf oc "\tfadd\t%s, %s, %s\n" (reg x) (reg y) (reg z)
- | NonTail(x), FSub(y, z) -> Printf.fprintf oc "\tfsub\t%s, %s, %s\n" (reg x) (reg y) (reg z)
- | NonTail(x), FMul(y, z) -> Printf.fprintf oc "\tfmul\t%s, %s, %s\n" (reg x) (reg y) (reg z)
- | NonTail(x), FDiv(y, z) -> Printf.fprintf oc "\tfdiv\t%s, %s, %s\n" (reg x) (reg y) (reg z)
+ | NonTail(x), FAdd(y, z) -> Printf.fprintf oc "\tvadd.f32 %s, %s, %s\n" (reg x) (reg y) (reg z)
+ | NonTail(x), FSub(y, z) -> Printf.fprintf oc "\tvsub.f32 %s, %s, %s\n" (reg x) (reg y) (reg z)
+ | NonTail(x), FMul(y, z) -> Printf.fprintf oc "\tvmul.f32 %s, %s, %s\n" (reg x) (reg y) (reg z)
+ | NonTail(x), FDiv(y, z) -> Printf.fprintf oc "\tvdiv.f32 %s, %s, %s\n" (reg x) (reg y) (reg z)
| NonTail(x), Lfd(y, V(z)) -> Printf.fprintf oc "\tlfdx\t%s, %s, %s\n" (reg x) (reg y) (reg z)
| NonTail(x), Lfd(y, C(z)) -> Printf.fprintf oc "\tvldr.32 %s, %s, %d\n" (reg x) (reg y) z | NonTail(_), Stfd(x, y, V(z)) -> Printf.fprintf oc "\tstfdx\t%s, %s, %s\n" (reg x) (reg y) (reg z)
@@ -110,19 +110,19 @@ and g' oc = function (* 各命令のアセンブリ生成 (caml2html: emit_gprim
(* 末尾だったら計算結果を第一レジスタにセットしてリターン (caml2html: emit_tailret) *)
| Tail, (Nop | Stw _ | Stfd _ | Comment _ | Save _ as exp) ->
g' oc (NonTail(Id.gentmp Type.Unit), exp);
- Printf.fprintf oc "\tblr\n";
+ Printf.fprintf oc "\tbx lr\n";
| Tail, (Li _ | SetL _ | Mr _ | Neg _ | Add _ | Sub _ | Slw _ | Lwz _ as exp) ->
g' oc (NonTail(regs.(0)), exp);
Printf.fprintf oc "\tbx lr\n";
| Tail, (FLi _ | FMr _ | FNeg _ | FAdd _ | FSub _ | FMul _ | FDiv _ | Lfd _ as exp) ->
g' oc (NonTail(fregs.(0)), exp);
- Printf.fprintf oc "\tblr\n";
+ Printf.fprintf oc "\tbx lr\n";
| Tail, (Restore(x) as exp) ->
(match locate x with
| i -> g' oc (NonTail(regs.(0)), exp) | i; j when i + 1 = j -> g' oc (NonTail(fregs.(0)), exp) | _ -> assert false);
- Printf.fprintf oc "\tblr\n";
+ Printf.fprintf oc "\tbx lr\n";
| Tail, IfEq(x, V(y), e1, e2) ->
Printf.fprintf oc "\tcmp %s, %s\n" (reg x) (reg y);
g'_tail_if oc e1 e2 "beq" "bne"
diff --git a/RP2350/libmincaml.S b/RP2350/libmincaml.S
index ea520f9..dc4a5b1 100644
--- a/RP2350/libmincaml.S
+++ b/RP2350/libmincaml.S
@@ -48,3 +48,12 @@ min_caml_int_of_float:
vcvt.s32.f32 s0, s0
vmov r0, s0
bx lr
+
+// float_of_int
+// r0: int value
+// return: float value
+ .globl min_caml_float_of_int
+min_caml_float_of_int:
+ vmov s0, r0
+ vcvt.f32.s32 s0, s0
+ bx lr
diff --git a/shootout/mandelbrot.ml b/shootout/mandelbrot.ml
index 2f656be..c5b799b 100644
--- a/shootout/mandelbrot.ml
+++ b/shootout/mandelbrot.ml
@@ -2,12 +2,12 @@
(*NOMINCAML let dbl f = 2. *. f in *)
(*NOMINCAML for y = 0 to 399 do *)
(*MINCAML*) let rec yloop y =
-(*MINCAML*) if y >= 400 then () else
+(*MINCAML*) if y >= 25 then () else
(*NOMINCAML for x = 0 to 399 do *)
(*MINCAML*) let rec xloop x y =
-(*MINCAML*) if x >= 400 then () else
- let cr = dbl (float_of_int x) /. 400.0 -. 1.5 in
- let ci = dbl (float_of_int y) /. 400.0 -. 1.0 in
+(*MINCAML*) if x >= 80 then () else
+ let cr = dbl (float_of_int x) /. 80.0 -. 1.5 in
+ let ci = dbl (float_of_int y) /. 25.0 -. 1.0 in
let rec iloop i zr zi zr2 zi2 cr ci =
if i = 0 then print_int 1 else
let tr = zr2 -. zi2 +. cr in
ラズピコ2実機で動かしてみる
生成した shootout/mandelbrot.s と libmincaml.S を、src/metro_rp2350_blink/ へコピー
CMakeLists.txt を修正して...
code:diff
diff --git a/CMakeLists.txt b/CMakeLists.txt
index dcf9a9e..4218d5a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,7 +9,7 @@ set(CMAKE_CXX_STANDARD 17)
pico_sdk_init()
-add_executable(metro_rp2350_blink main.c)
+add_executable(metro_rp2350_blink libmincaml.s mandelbrot.s main.c)
target_link_libraries(metro_rp2350_blink pico_stdlib)
ビルドする
code:sh
$ cmake --build build
生成された metro_rp2350_blink.uf2 をラズピコ2へ書き込む
https://gyazo.com/c360a793b01718d56f62891cf8ba09b5
USBシリアルからの出力を確認。いい感じに出力されてそう
code:sh
$ cat /dev/cu.usbmodem1101
https://gyazo.com/c0ca1bb8562c2027e18496aa681392a6