@@ -984,11 +984,13 @@ impl MachInstEmit for Inst {
984984 & Inst :: BrTable {
985985 index,
986986 tmp1,
987+ tmp2,
987988 ref targets,
988989 } => {
989990 let index = allocs. next ( index) ;
990991 let tmp1 = allocs. next_writable ( tmp1) ;
991- let tmp2 = writable_spilltmp_reg ( ) ;
992+ let tmp2 = allocs. next_writable ( tmp2) ;
993+ let ext_index = writable_spilltmp_reg ( ) ;
992994
993995 // The default target is passed in as the 0th element of `targets`
994996 // separate it here for clarity.
@@ -1001,22 +1003,38 @@ impl MachInstEmit for Inst {
10011003 // that offset. Each jump table entry is a regular auipc+jalr which we emit sequentially.
10021004 //
10031005 // Build the following sequence:
1006+ //
1007+ // extend_index:
1008+ // zext.w ext_index, index
10041009 // bounds_check:
10051010 // li tmp, n_labels
1006- // bltu index , tmp, compute_target
1011+ // bltu ext_index , tmp, compute_target
10071012 // jump_to_default_block:
10081013 // auipc pc, 0
10091014 // jalr zero, pc, default_block
10101015 // compute_target:
10111016 // auipc pc, 0
1012- // slli tmp, index , 3
1017+ // slli tmp, ext_index , 3
10131018 // add pc, pc, tmp
10141019 // jalr zero, pc, 0x10
10151020 // jump_table:
10161021 // ; This repeats for each entry in the jumptable
10171022 // auipc pc, 0
10181023 // jalr zero, pc, block_target
10191024
1025+ // Extend the index to 64 bits.
1026+ //
1027+ // This prevents us branching on the top 32 bits of the index, which
1028+ // are undefined.
1029+ Inst :: Extend {
1030+ rd : ext_index,
1031+ rn : index,
1032+ signed : false ,
1033+ from_bits : 32 ,
1034+ to_bits : 64 ,
1035+ }
1036+ . emit ( & [ ] , sink, emit_info, state) ;
1037+
10201038 // Bounds check.
10211039 //
10221040 // Check if the index passed in is larger than the number of jumptable
@@ -1030,7 +1048,7 @@ impl MachInstEmit for Inst {
10301048 not_taken : BranchTarget :: zero ( ) ,
10311049 kind : IntegerCompare {
10321050 kind : IntCC :: UnsignedLessThan ,
1033- rs1 : index ,
1051+ rs1 : ext_index . to_reg ( ) ,
10341052 rs2 : tmp2. to_reg ( ) ,
10351053 } ,
10361054 }
@@ -1059,7 +1077,7 @@ impl MachInstEmit for Inst {
10591077 Inst :: AluRRImm12 {
10601078 alu_op : AluOPRRI :: Slli ,
10611079 rd : tmp2,
1062- rs : index ,
1080+ rs : ext_index . to_reg ( ) ,
10631081 imm12 : Imm12 :: from_bits ( 3 ) ,
10641082 }
10651083 . emit ( & [ ] , sink, emit_info, state) ;
0 commit comments