@@ -31,15 +31,22 @@ pub fn lower(mut m mir.Module, arch pref.Arch) {
3131}
3232
3333pub fn lower_with_x64_abi (mut m mir.Module, arch pref.Arch, x64_ abi X64 Abi) {
34+ is_x64 := arch == .x64
3435 mut fn_by_name := map [string ]int {}
3536 for i := 0 ; i < m.funcs.len; i++ {
3637 mut f := & m.funcs[i]
3738 fn_by_name[f.name] = i
38- f.abi_ret_class = abi_value_class (m, f.typ, arch, x64_ abi)
39- f.abi_ret_indirect = abi_class_is_indirect (f.abi_ret_class, m, f.typ, arch, x64_ abi)
39+ if is_x64 {
40+ f.abi_ret_class = abi_value_class (m, f.typ, arch, x64_ abi)
41+ f.abi_ret_indirect = abi_class_is_indirect (f.abi_ret_class, m, f.typ, arch, x64_ abi)
42+ } else {
43+ f.abi_ret_indirect = needs_indirect (m, f.typ, arch, x64_ abi)
44+ }
4045 f.abi_param_class = []mir.AbiArgClass{len: f.params.len, init: .in_reg}
41- f.abi_param_classes = []mir.AbiValueClass{len: f.params.len}
42- f.abi_param_layouts = []mir.AbiValueLayout{len: f.params.len}
46+ if is_x64 {
47+ f.abi_param_classes = []mir.AbiValueClass{len: f.params.len}
48+ f.abi_param_layouts = []mir.AbiValueLayout{len: f.params.len}
49+ }
4350 mut param_loc_state := SysVLocationState{}
4451 if arch == .x64 && x64_abi == .sysv && f.abi_ret_indirect {
4552 param_loc_state.int_regs = 1
@@ -49,12 +56,17 @@ pub fn lower_with_x64_abi(mut m mir.Module, arch pref.Arch, x64_abi X64Abi) {
4956 continue
5057 }
5158 param_typ := m.values[param_id].typ
52- param_class := abi_value_class (m, param_typ, arch, x64_ abi)
53- f.abi_param_classes[pi] = param_class
54- if arch == .x64 && x64_abi == .sysv {
55- f.abi_param_layouts[pi] = sysv_assign_value_layout (param_class, mut param_loc_state)
56- }
57- if abi_class_is_indirect (param_class, m, param_typ, arch, x64_ abi) {
59+ if is_x64 {
60+ param_class := abi_value_class (m, param_typ, arch, x64_ abi)
61+ f.abi_param_classes[pi] = param_class
62+ if x64_abi == .sysv {
63+ f.abi_param_layouts[pi] = sysv_assign_value_layout (param_class, mut
64+ param_loc_state)
65+ }
66+ if abi_class_is_indirect (param_class, m, param_typ, arch, x64_ abi) {
67+ f.abi_param_class[pi] = .indirect
68+ }
69+ } else if needs_indirect (m, param_typ, arch, x64_ abi) {
5870 f.abi_param_class[pi] = .indirect
5971 }
6072 }
@@ -505,19 +517,30 @@ fn lower_calls(mut m mir.Module, arch pref.Arch, x64_abi X64Abi, fn_by_name map[
505517 if arch ! in [.arm64 , .x64 ] {
506518 return
507519 }
520+ is_x64 := arch == .x64
508521
509522 for i := 0 ; i < m.instrs.len; i++ {
510523 mut instr := & m.instrs[i]
511524 if instr.op ! in [.call, .call_indirect, .call_sret] || instr.operands.len == 0 {
512525 continue
513526 }
514527 ret_typ , sig_param_types := call_signature (m, instr, fn_by_name)
515- ret_class := abi_value_class (m, ret_typ, arch, x64_ abi)
516- ret_indirect := abi_class_is_indirect (ret_class, m, ret_typ, arch, x64_ abi)
528+ ret_class := if is_x64 {
529+ abi_value_class (m, ret_typ, arch, x64_ abi)
530+ } else {
531+ mir.AbiValueClass{}
532+ }
533+ ret_indirect := if is_x64 {
534+ abi_class_is_indirect (ret_class, m, ret_typ, arch, x64_ abi)
535+ } else {
536+ needs_indirect (m, ret_typ, arch, x64_ abi)
537+ }
517538 num_args := instr.operands.len - 1
518539 instr.abi_arg_class = []mir.AbiArgClass{len: num_args, init: .in_reg}
519- instr.abi_arg_classes = []mir.AbiValueClass{len: num_args}
520- instr.abi_arg_layouts = []mir.AbiValueLayout{len: num_args}
540+ if is_x64 {
541+ instr.abi_arg_classes = []mir.AbiValueClass{len: num_args}
542+ instr.abi_arg_layouts = []mir.AbiValueLayout{len: num_args}
543+ }
521544 mut arg_loc_state := SysVLocationState{}
522545 if arch == .x64 && x64_abi == .sysv && ret_indirect {
523546 arg_loc_state.int_regs = 1
@@ -530,13 +553,17 @@ fn lower_calls(mut m mir.Module, arch pref.Arch, x64_abi X64Abi, fn_by_name map[
530553 arg_id := instr.operands[arg_idx + 1 ]
531554 arg_typ = fallback_arg_type (m, arg_id)
532555 }
533- arg_class := abi_value_class (m, arg_typ, arch, x64_ abi)
534- instr.abi_arg_classes[arg_idx] = arg_class
535- if arch == .x64 && x64_abi == .sysv {
536- instr.abi_arg_layouts[arg_idx] = sysv_assign_value_layout (arg_class, mut
537- arg_loc_state)
538- }
539- if abi_class_is_indirect (arg_class, m, arg_typ, arch, x64_ abi) {
556+ if is_x64 {
557+ arg_class := abi_value_class (m, arg_typ, arch, x64_ abi)
558+ instr.abi_arg_classes[arg_idx] = arg_class
559+ if x64_abi == .sysv {
560+ instr.abi_arg_layouts[arg_idx] = sysv_assign_value_layout (arg_class, mut
561+ arg_loc_state)
562+ }
563+ if abi_class_is_indirect (arg_class, m, arg_typ, arch, x64_ abi) {
564+ instr.abi_arg_class[arg_idx] = .indirect
565+ }
566+ } else if needs_indirect (m, arg_typ, arch, x64_ abi) {
540567 instr.abi_arg_class[arg_idx] = .indirect
541568 }
542569 }
0 commit comments