Skip to content

Commit 4e8fd9b

Browse files
committed
riscv32: Convert placeholders to FFFFFFFF for embedded JIT
Signed-off-by: Paul Guyot <[email protected]>
1 parent 6039138 commit 4e8fd9b

File tree

1 file changed

+29
-25
lines changed

1 file changed

+29
-25
lines changed

libs/jit/src/jit_riscv32.erl

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -903,7 +903,8 @@ if_else_block(
903903
Stream2 = State2#state.stream,
904904
%% Emit unconditional branch to skip the else block (will be replaced)
905905
ElseJumpOffset = StreamModule:offset(Stream2),
906-
ElseJumpInstr = jit_riscv32_asm:j(0),
906+
%% Use all-1s placeholder for flash compatibility (can only flip 1->0)
907+
ElseJumpInstr = <<16#FFFF:16>>,
907908
Stream3 = StreamModule:append(Stream2, ElseJumpInstr),
908909
%% Else block starts here.
909910
OffsetAfter = StreamModule:offset(Stream3),
@@ -923,6 +924,9 @@ if_else_block(
923924
%% Patch the unconditional branch to jump to the end
924925
FinalJumpOffset = OffsetFinal - ElseJumpOffset,
925926
NewElseJumpInstr = jit_riscv32_asm:j(FinalJumpOffset),
927+
%% Assert that replacement is 2 bytes (c.j range: -2048..2046)
928+
%% If this fails, the if/else blocks are too large
929+
2 = byte_size(NewElseJumpInstr),
926930
Stream6 = StreamModule:replace(Stream5, ElseJumpOffset, NewElseJumpInstr),
927931
merge_used_regs(State3#state{stream = Stream6}, State2#state.used_regs).
928932

@@ -934,7 +938,7 @@ if_else_block(
934938
}.
935939
if_block_cond(#state{stream_module = StreamModule, stream = Stream0} = State0, {Reg, '<', 0}) ->
936940
%% RISC-V: bge Reg, zero, offset (branch if Reg >= 0, i.e., NOT negative/NOT less than 0)
937-
BranchInstr = jit_riscv32_asm:bge(Reg, zero, 0),
941+
BranchInstr = <<16#FFFFFFFF:32/little>>,
938942
Stream1 = StreamModule:append(Stream0, BranchInstr),
939943
State1 = State0#state{stream = Stream1},
940944
{State1, {bge, Reg, zero}, 0};
@@ -949,7 +953,7 @@ if_block_cond(
949953
State1 = mov_immediate(State0, Temp, Val),
950954
Stream1 = State1#state.stream,
951955
BranchDelta = StreamModule:offset(Stream1) - OffsetBefore,
952-
BranchInstr = jit_riscv32_asm:bge(Reg, Temp, 0),
956+
BranchInstr = <<16#FFFFFFFF:32/little>>,
953957
Stream2 = StreamModule:append(Stream1, BranchInstr),
954958
State2 = State1#state{stream = Stream2},
955959
{State2, {bge, Reg, Temp}, BranchDelta};
@@ -962,7 +966,7 @@ if_block_cond(
962966
State1 = mov_immediate(State0, Temp, Val),
963967
Stream1 = State1#state.stream,
964968
BranchDelta = StreamModule:offset(Stream1) - OffsetBefore,
965-
BranchInstr = jit_riscv32_asm:bge(Reg, Temp, 0),
969+
BranchInstr = <<16#FFFFFFFF:32/little>>,
966970
Stream2 = StreamModule:append(Stream1, BranchInstr),
967971
State2 = State1#state{stream = Stream2},
968972
{State2, {bge, Reg, Temp}, BranchDelta};
@@ -976,7 +980,7 @@ if_block_cond(
976980
RegOrTuple -> RegOrTuple
977981
end,
978982
% RISC-V: bge Reg, RegB, offset (branch if Reg >= RegB, i.e., NOT less than)
979-
BranchInstr = jit_riscv32_asm:bge(Reg, RegB, 0),
983+
BranchInstr = <<16#FFFFFFFF:32/little>>,
980984
Stream1 = StreamModule:append(Stream0, BranchInstr),
981985
State1 = if_block_free_reg(RegOrTuple, State0),
982986
State2 = State1#state{stream = Stream1},
@@ -990,7 +994,7 @@ if_block_cond(
990994
RegOrTuple -> RegOrTuple
991995
end,
992996
%% RISC-V: bne Reg, zero, offset (branch if Reg != 0, i.e., NOT equal to 0)
993-
BranchInstr = jit_riscv32_asm:bne(Reg, zero, 0),
997+
BranchInstr = <<16#FFFFFFFF:32/little>>,
994998
Stream1 = StreamModule:append(Stream0, BranchInstr),
995999
State1 = if_block_free_reg(RegOrTuple, State0),
9961000
State2 = State1#state{stream = Stream1},
@@ -1005,7 +1009,7 @@ if_block_cond(
10051009
RegOrTuple -> RegOrTuple
10061010
end,
10071011
%% RISC-V: bne Reg, RegB, offset (branch if Reg != RegB, i.e., NOT equal)
1008-
BranchInstr = jit_riscv32_asm:bne(Reg, RegB, 0),
1012+
BranchInstr = <<16#FFFFFFFF:32/little>>,
10091013
Stream1 = StreamModule:append(Stream0, BranchInstr),
10101014
State1 = if_block_free_reg(RegOrTuple, State0),
10111015
State2 = State1#state{stream = Stream1},
@@ -1029,7 +1033,7 @@ if_block_cond(
10291033
State1 = mov_immediate(State0, Temp, Val),
10301034
Stream1 = State1#state.stream,
10311035
BranchDelta = StreamModule:offset(Stream1) - OffsetBefore,
1032-
BranchInstr = jit_riscv32_asm:beq(Reg, Temp, 0),
1036+
BranchInstr = <<16#FFFFFFFF:32/little>>,
10331037
Stream2 = StreamModule:append(Stream1, BranchInstr),
10341038
State2 = if_block_free_reg(RegOrTuple, State1),
10351039
State3 = State2#state{stream = Stream2},
@@ -1044,7 +1048,7 @@ if_block_cond(
10441048
RegOrTuple -> RegOrTuple
10451049
end,
10461050
%% RISC-V: beq Reg, Val, offset (branch if Reg == Val, i.e., NOT not-equal)
1047-
BranchInstr = jit_riscv32_asm:beq(Reg, Val, 0),
1051+
BranchInstr = <<16#FFFFFFFF:32/little>>,
10481052
Stream1 = StreamModule:append(Stream0, BranchInstr),
10491053
State1 = if_block_free_reg(RegOrTuple, State0),
10501054
State2 = State1#state{stream = Stream1},
@@ -1065,7 +1069,7 @@ if_block_cond(
10651069
State1 = mov_immediate(State0, Temp, Val),
10661070
Stream1 = State1#state.stream,
10671071
BranchDelta = StreamModule:offset(Stream1) - OffsetBefore,
1068-
BranchInstr = jit_riscv32_asm:bne(Reg, Temp, 0),
1072+
BranchInstr = <<16#FFFFFFFF:32/little>>,
10691073
Stream2 = StreamModule:append(Stream1, BranchInstr),
10701074
State2 = if_block_free_reg(RegOrTuple, State1),
10711075
State3 = State2#state{stream = Stream2},
@@ -1075,7 +1079,7 @@ if_block_cond(
10751079
{{free, RegA}, '==', {free, RegB}}
10761080
) ->
10771081
%% RISC-V: bne RegA, RegB, offset (branch if RegA != RegB, i.e., NOT equal)
1078-
BranchInstr = jit_riscv32_asm:bne(RegA, RegB, 0),
1082+
BranchInstr = <<16#FFFFFFFF:32/little>>,
10791083
Stream1 = StreamModule:append(Stream0, BranchInstr),
10801084
State1 = State0#state{stream = Stream1},
10811085
State2 = if_block_free_reg({free, RegA}, State1),
@@ -1095,7 +1099,7 @@ if_block_cond(
10951099
Stream1 = State1#state.stream,
10961100
BranchDelta = StreamModule:offset(Stream1) - OffsetBefore,
10971101
%% RISC-V: bne Reg, Temp, offset (branch if Reg != Temp, i.e., NOT equal)
1098-
BranchInstr = jit_riscv32_asm:bne(Reg, Temp, 0),
1102+
BranchInstr = <<16#FFFFFFFF:32/little>>,
10991103
Stream2 = StreamModule:append(Stream1, BranchInstr),
11001104
State2 = if_block_free_reg(RegOrTuple, State1),
11011105
State3 = State2#state{stream = Stream2},
@@ -1114,7 +1118,7 @@ if_block_cond(
11141118
Stream1 = State1#state.stream,
11151119
BranchDelta = StreamModule:offset(Stream1) - OffsetBefore,
11161120
%% RISC-V: beq Reg, Temp, offset (branch if Reg == Temp, i.e., NOT not-equal)
1117-
BranchInstr = jit_riscv32_asm:beq(Reg, Temp, 0),
1121+
BranchInstr = <<16#FFFFFFFF:32/little>>,
11181122
Stream2 = StreamModule:append(Stream1, BranchInstr),
11191123
State2 = if_block_free_reg(RegOrTuple, State1),
11201124
State3 = State2#state{stream = Stream2},
@@ -1135,7 +1139,7 @@ if_block_cond(
11351139
%% RISC-V: Test bit 0 by shifting to MSB, then branch if negative (bit was 1, NOT false)
11361140
I1 = jit_riscv32_asm:slli(Temp, Reg, 31),
11371141
Stream1 = StreamModule:append(Stream0, I1),
1138-
BranchInstr = jit_riscv32_asm:blt(Temp, zero, 0),
1142+
BranchInstr = <<16#FFFFFFFF:32/little>>,
11391143
Stream2 = StreamModule:append(Stream1, BranchInstr),
11401144
State1 = if_block_free_reg(RegOrTuple, State0),
11411145
State2 = State1#state{stream = Stream2},
@@ -1156,7 +1160,7 @@ if_block_cond(
11561160
%% RISC-V: Test bit 0 by shifting to MSB, then branch if non-negative (bit was 0, NOT true)
11571161
I1 = jit_riscv32_asm:slli(Temp, Reg, 31),
11581162
Stream1 = StreamModule:append(Stream0, I1),
1159-
BranchInstr = jit_riscv32_asm:bge(Temp, zero, 0),
1163+
BranchInstr = <<16#FFFFFFFF:32/little>>,
11601164
Stream2 = StreamModule:append(Stream1, BranchInstr),
11611165
State1 = if_block_free_reg(RegOrTuple, State0),
11621166
State2 = State1#state{stream = Stream2},
@@ -1190,7 +1194,7 @@ if_block_cond(
11901194
Stream1 = StreamModule:append(Stream0, TestCode),
11911195
BranchDelta = StreamModule:offset(Stream1) - OffsetBefore,
11921196
%% Branch if result is zero (no bits set, NOT != 0)
1193-
BranchInstr = jit_riscv32_asm:beq(Temp, zero, 0),
1197+
BranchInstr = <<16#FFFFFFFF:32/little>>,
11941198
Stream2 = StreamModule:append(Stream1, BranchInstr),
11951199
State1 = if_block_free_reg(RegOrTuple, State0),
11961200
State2 = State1#state{stream = Stream2},
@@ -1207,7 +1211,7 @@ if_block_cond(
12071211
I1 = jit_riscv32_asm:not_(Temp, Reg),
12081212
I2 = jit_riscv32_asm:slli(Temp, Temp, 28),
12091213
Stream1 = StreamModule:append(Stream0, <<I1/binary, I2/binary>>),
1210-
BranchInstr = jit_riscv32_asm:beq(Temp, zero, 0),
1214+
BranchInstr = <<16#FFFFFFFF:32/little>>,
12111215
Stream2 = StreamModule:append(Stream1, BranchInstr),
12121216
State1 = State0#state{stream = Stream2},
12131217
{State1, {beq, Temp, zero}, byte_size(I1) + byte_size(I2)};
@@ -1222,7 +1226,7 @@ if_block_cond(
12221226
I1 = jit_riscv32_asm:not_(Reg, Reg),
12231227
I2 = jit_riscv32_asm:slli(Reg, Reg, 28),
12241228
Stream1 = StreamModule:append(Stream0, <<I1/binary, I2/binary>>),
1225-
BranchInstr = jit_riscv32_asm:beq(Reg, zero, 0),
1229+
BranchInstr = <<16#FFFFFFFF:32/little>>,
12261230
Stream2 = StreamModule:append(Stream1, BranchInstr),
12271231
State1 = State0#state{stream = Stream2},
12281232
State2 = if_block_free_reg(RegTuple, State1),
@@ -1247,7 +1251,7 @@ if_block_cond(
12471251
0 ->
12481252
%% Optimize comparison with zero
12491253
BranchDelta = StreamModule:offset(Stream2) - OffsetBefore,
1250-
BranchInstr = jit_riscv32_asm:beq(Temp, zero, 0),
1254+
BranchInstr = <<16#FFFFFFFF:32/little>>,
12511255
Stream3 = StreamModule:append(Stream2, BranchInstr),
12521256
State3 = State2#state{
12531257
stream = Stream3, available_regs = [Temp | State2#state.available_regs]
@@ -1256,7 +1260,7 @@ if_block_cond(
12561260
_ when ?IS_GPR(Val) ->
12571261
%% Val is a register
12581262
BranchDelta = StreamModule:offset(Stream2) - OffsetBefore,
1259-
BranchInstr = jit_riscv32_asm:beq(Temp, Val, 0),
1263+
BranchInstr = <<16#FFFFFFFF:32/little>>,
12601264
Stream3 = StreamModule:append(Stream2, BranchInstr),
12611265
State3 = State2#state{
12621266
stream = Stream3, available_regs = [Temp | State2#state.available_regs]
@@ -1269,7 +1273,7 @@ if_block_cond(
12691273
State3 = mov_immediate(State2#state{available_regs = AT2}, MaskReg, Val),
12701274
Stream3 = State3#state.stream,
12711275
BranchDelta = StreamModule:offset(Stream3) - OffsetBefore,
1272-
BranchInstr = jit_riscv32_asm:beq(Temp, MaskReg, 0),
1276+
BranchInstr = <<16#FFFFFFFF:32/little>>,
12731277
Stream4 = StreamModule:append(Stream3, BranchInstr),
12741278
State4 = State3#state{
12751279
stream = Stream4, available_regs = [Temp, MaskReg | State3#state.available_regs]
@@ -1293,15 +1297,15 @@ if_block_cond(
12931297
0 ->
12941298
%% Optimize comparison with zero
12951299
BranchDelta = StreamModule:offset(Stream1) - OffsetBefore,
1296-
BranchInstr = jit_riscv32_asm:beq(Reg, zero, 0),
1300+
BranchInstr = <<16#FFFFFFFF:32/little>>,
12971301
Stream2 = StreamModule:append(Stream1, BranchInstr),
12981302
State2 = State1#state{stream = Stream2},
12991303
State3 = if_block_free_reg(RegTuple, State2),
13001304
{State3, {beq, Reg, zero}, BranchDelta};
13011305
_ when ?IS_GPR(Val) ->
13021306
%% Val is a register
13031307
BranchDelta = StreamModule:offset(Stream1) - OffsetBefore,
1304-
BranchInstr = jit_riscv32_asm:beq(Reg, Val, 0),
1308+
BranchInstr = <<16#FFFFFFFF:32/little>>,
13051309
Stream2 = StreamModule:append(Stream1, BranchInstr),
13061310
State2 = State1#state{stream = Stream2},
13071311
State3 = if_block_free_reg(RegTuple, State2),
@@ -1313,7 +1317,7 @@ if_block_cond(
13131317
State2 = mov_immediate(State1#state{available_regs = AT}, MaskReg, Val),
13141318
Stream2 = State2#state.stream,
13151319
BranchDelta = StreamModule:offset(Stream2) - OffsetBefore,
1316-
BranchInstr = jit_riscv32_asm:beq(Reg, MaskReg, 0),
1320+
BranchInstr = <<16#FFFFFFFF:32/little>>,
13171321
Stream3 = StreamModule:append(Stream2, BranchInstr),
13181322
State3 = State2#state{stream = Stream3, available_regs = AvailRegs},
13191323
State4 = if_block_free_reg(RegTuple, State3),
@@ -2643,7 +2647,7 @@ decrement_reductions_and_maybe_schedule_next(
26432647
Stream1 = StreamModule:append(Stream0, <<I1/binary, I2/binary, I3/binary>>),
26442648
BNEOffset = StreamModule:offset(Stream1),
26452649
% Branch if reduction count is not zero
2646-
I4 = jit_riscv32_asm:bne(Temp, zero, 0),
2650+
I4 = <<16#FFFFFFFF:32/little>>,
26472651
% Set continuation to the next instruction
26482652
ADROffset = BNEOffset + byte_size(I4),
26492653
% Use 8-byte placeholder (2 words of 0xFFFFFFFF) for pc_relative_address

0 commit comments

Comments
 (0)