@@ -194,7 +194,7 @@ impl MachineLower for X64Machine {
194194 // `setcc` output register.
195195 emit_setcc_sequence ( ctx, output, |ctx| select_icmp ( ctx, node, kind) ) ;
196196 }
197- & NodeKind :: Fconst64 ( val) => select_fconst64 ( ctx, node, val) ,
197+ & NodeKind :: Fconst64 ( val) => select_fconst64 ( self , ctx, node, val) ,
198198 NodeKind :: Fadd => emit_fpu_rr ( ctx, node, SseFpuBinOp :: Add ) ,
199199 NodeKind :: Fsub => emit_fpu_rr ( ctx, node, SseFpuBinOp :: Sub ) ,
200200 NodeKind :: Fmul => emit_fpu_rr ( ctx, node, SseFpuBinOp :: Mul ) ,
@@ -405,18 +405,47 @@ fn select_icmp(ctx: &mut IselContext<'_, '_, X64Machine>, node: Node, kind: Icmp
405405 cond_code_for_icmp ( kind)
406406}
407407
408- fn select_fconst64 ( ctx : & mut IselContext < ' _ , ' _ , X64Machine > , node : Node , val : BitwiseF64 ) {
408+ fn select_fconst64 (
409+ machine : & X64Machine ,
410+ ctx : & mut IselContext < ' _ , ' _ , X64Machine > ,
411+ node : Node ,
412+ val : BitwiseF64 ,
413+ ) {
409414 let [ output] = ctx. node_outputs_exact ( node) ;
410415 let output = ctx. get_value_vreg ( output) ;
411416
412417 if val. bits ( ) == 0 {
413418 ctx. emit_instr ( X64Instr :: SseMovRZ , & [ DefOperand :: any_reg ( output) ] , & [ ] ) ;
414419 } else {
415- ctx. emit_instr (
416- X64Instr :: MovsdConstRel ( val. 0 ) ,
417- & [ DefOperand :: any_reg ( output) ] ,
418- & [ ] ,
419- ) ;
420+ match machine. config . internal_code_model {
421+ CodeModel :: SmallPic => {
422+ ctx. emit_instr (
423+ X64Instr :: MovsdConstRel ( val. 0 ) ,
424+ & [ DefOperand :: any_reg ( output) ] ,
425+ & [ ] ,
426+ ) ;
427+ }
428+ CodeModel :: LargeAbs => {
429+ let addr = ctx. create_temp_vreg ( RC_GPR ) ;
430+ ctx. emit_instr (
431+ X64Instr :: F64ConstAddrAbs ( val. 0 ) ,
432+ & [ DefOperand :: any_reg ( addr) ] ,
433+ & [ ] ,
434+ ) ;
435+ ctx. emit_instr (
436+ X64Instr :: MovsRM (
437+ SseFpuPrecision :: Double ,
438+ AddrMode {
439+ base : Some ( AddrBase :: Reg ) ,
440+ index : None ,
441+ offset : 0 ,
442+ } ,
443+ ) ,
444+ & [ DefOperand :: any_reg ( output) ] ,
445+ & [ UseOperand :: any_reg ( addr) ] ,
446+ ) ;
447+ }
448+ }
420449 }
421450}
422451
0 commit comments