authorgravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-03-18 21:30:06+01:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2025-03-19 03:15:16+01:00
log03123916e55a9c0c8b66f748a62b7a4a64203535
tree0f131e75bc299b5c567e9e3f30ba3b9b7fff70d3
parent5105c3c7fa46969dc731b7447415436fd7572e87

compiler: Support more GCC code models and fix the mapping to LLVM code models.

Closes #22517.

3 files changed, 56 insertions(+), 15 deletions(-)

lib/std/builtin.zig+8-3
......@@ -141,11 +141,16 @@ pub const AtomicRmwOp = enum {
141141/// therefore must be kept in sync with the compiler implementation.
142142pub const CodeModel = enum {
143143 default,
144 tiny,
145 small,
144 extreme,
146145 kernel,
147 medium,
148146 large,
147 medany,
148 medium,
149 medlow,
150 medmid,
151 normal,
152 small,
153 tiny,
149154};
150155
151156/// This data structure is used by the Zig language code generation and
src/codegen/llvm.zig+36-9
......@@ -457,6 +457,30 @@ pub fn dataLayout(target: std.Target) []const u8 {
457457 };
458458}
459459
460// Avoid depending on `llvm.CodeModel` in the bitcode-only case.
461const CodeModel = enum {
462 default,
463 tiny,
464 small,
465 kernel,
466 medium,
467 large,
468};
469
470fn codeModel(model: std.builtin.CodeModel, target: std.Target) CodeModel {
471 // Roughly match Clang's mapping of GCC code models to LLVM code models.
472 return switch (model) {
473 .default => .default,
474 .extreme, .large => .large,
475 .kernel => .kernel,
476 .medany => if (target.cpu.arch.isRISCV()) .medium else .large,
477 .medium => if (target.os.tag == .aix) .large else .medium,
478 .medmid => .medium,
479 .normal, .medlow, .small => .small,
480 .tiny => .tiny,
481 };
482}
483
460484pub const Object = struct {
461485 gpa: Allocator,
462486 builder: Builder,
......@@ -821,14 +845,17 @@ pub const Object = struct {
821845 module_flags.appendAssumeCapacity(try o.builder.metadataModuleFlag(
822846 behavior_error,
823847 try o.builder.metadataString("Code Model"),
824 try o.builder.metadataConstant(try o.builder.intConst(.i32, @as(i32, switch (comp.root_mod.code_model) {
825 .tiny => 0,
826 .small => 1,
827 .kernel => 2,
828 .medium => 3,
829 .large => 4,
830 else => unreachable,
831 }))),
848 try o.builder.metadataConstant(try o.builder.intConst(.i32, @as(
849 i32,
850 switch (codeModel(comp.root_mod.code_model, comp.root_mod.resolved_target.result)) {
851 .default => unreachable,
852 .tiny => 0,
853 .small => 1,
854 .kernel => 2,
855 .medium => 3,
856 .large => 4,
857 },
858 ))),
832859 ));
833860 }
834861
......@@ -980,7 +1007,7 @@ pub const Object = struct {
9801007 else
9811008 .Static;
9821009
983 const code_model: llvm.CodeModel = switch (comp.root_mod.code_model) {
1010 const code_model: llvm.CodeModel = switch (codeModel(comp.root_mod.code_model, comp.root_mod.resolved_target.result)) {
9841011 .default => .Default,
9851012 .tiny => .Tiny,
9861013 .small => .Small,
src/main.zig+12-3
......@@ -499,9 +499,18 @@ const usage_build_generic =
499499 \\ hex (planned feature) Intel IHEX
500500 \\ raw (planned feature) Dump machine code directly
501501 \\ -mcpu [cpu] Specify target CPU and feature set
502 \\ -mcmodel=[default|tiny| Limit range of code and data virtual addresses
503 \\ small|kernel|
504 \\ medium|large]
502 \\ -mcmodel=[model] Limit range of code and data virtual addresses
503 \\ default
504 \\ extreme
505 \\ kernel
506 \\ large
507 \\ medany
508 \\ medium
509 \\ medlow
510 \\ medmid
511 \\ normal
512 \\ small
513 \\ tiny
505514 \\ -mred-zone Force-enable the "red-zone"
506515 \\ -mno-red-zone Force-disable the "red-zone"
507516 \\ -fomit-frame-pointer Omit the stack frame pointer