Browse Source

Add `-build-mode:assembly` for `-llvm-api`

gingerBill 4 years ago
parent
commit
4e5b8f2c61
3 changed files with 40 additions and 18 deletions
  1. 1 0
      src/build_settings.cpp
  2. 22 14
      src/llvm_backend.cpp
  3. 17 4
      src/main.cpp

+ 1 - 0
src/build_settings.cpp

@@ -101,6 +101,7 @@ enum BuildModeKind {
 	BuildMode_Executable,
 	BuildMode_DynamicLibrary,
 	BuildMode_Object,
+	BuildMode_Assembly,
 };
 
 

+ 22 - 14
src/llvm_backend.cpp

@@ -11872,9 +11872,12 @@ void lb_generate_code(lbGenerator *gen) {
 		}
 	}
 
+	// GB_ASSERT_MSG(LLVMTargetHasAsmBackend(target));
+
 	LLVMTargetMachineRef target_machine = LLVMCreateTargetMachine(target, target_triple, llvm_cpu, llvm_features, LLVMCodeGenLevelNone, LLVMRelocDefault, code_mode);
 	defer (LLVMDisposeTargetMachine(target_machine));
 
+
 	LLVMSetModuleDataLayout(mod, LLVMCreateTargetDataLayout(target_machine));
 
 	{ // Debug Info
@@ -12461,18 +12464,25 @@ void lb_generate_code(lbGenerator *gen) {
 	defer (gb_free(heap_allocator(), filepath_ll.text));
 
 	String filepath_obj = {};
-	switch (build_context.metrics.os) {
-	case TargetOs_windows:
-		filepath_obj = concatenate_strings(heap_allocator(), gen->output_base, STR_LIT(".obj"));
-		break;
-	case TargetOs_darwin:
-	case TargetOs_linux:
-	case TargetOs_essence:
-		filepath_obj = concatenate_strings(heap_allocator(), gen->output_base, STR_LIT(".o"));
-		break;
-	case TargetOs_js:
-		filepath_obj = concatenate_strings(heap_allocator(), gen->output_base, STR_LIT(".wasm-obj"));
-		break;
+	LLVMCodeGenFileType code_gen_file_type = LLVMObjectFile;
+
+	if (build_context.build_mode == BuildMode_Assembly) {
+		filepath_obj = concatenate_strings(heap_allocator(), gen->output_base, STR_LIT(".S"));
+		code_gen_file_type = LLVMAssemblyFile;
+	} else {
+		switch (build_context.metrics.os) {
+		case TargetOs_windows:
+			filepath_obj = concatenate_strings(heap_allocator(), gen->output_base, STR_LIT(".obj"));
+			break;
+		case TargetOs_darwin:
+		case TargetOs_linux:
+		case TargetOs_essence:
+			filepath_obj = concatenate_strings(heap_allocator(), gen->output_base, STR_LIT(".o"));
+			break;
+		case TargetOs_js:
+			filepath_obj = concatenate_strings(heap_allocator(), gen->output_base, STR_LIT(".wasm-obj"));
+			break;
+		}
 	}
 
 
@@ -12492,8 +12502,6 @@ void lb_generate_code(lbGenerator *gen) {
 
 	TIME_SECTION("LLVM Object Generation");
 
-	LLVMCodeGenFileType code_gen_file_type = LLVMObjectFile;
-
 	if (LLVMTargetMachineEmitToFile(target_machine, mod, cast(char *)filepath_obj.text, code_gen_file_type, &llvm_error)) {
 		gb_printf_err("LLVM Error: %s\n", llvm_error);
 		gb_exit(1);

+ 17 - 4
src/main.cpp

@@ -1061,6 +1061,8 @@ bool parse_build_flags(Array<String> args) {
 								build_context.build_mode = BuildMode_Object;
 							} else if (str == "exe") {
 								build_context.build_mode = BuildMode_Executable;
+							} else if (str == "asm" || str == "assembly" || str == "assembler") {
+								build_context.build_mode = BuildMode_Assembly;
 							} else {
 								gb_printf_err("Unknown build mode '%.*s'\n", LIT(str));
 								bad_flags = true;
@@ -1762,6 +1764,12 @@ int main(int arg_count, char const **arg_ptr) {
 			return 1;
 		}
 	}
+	if (!build_context.use_llvm_api) {
+		if (build_context.build_mode == BuildMode_Assembly) {
+			print_usage_line(0, "-build-mode:assembly is only supported with the -llvm-api backend", LIT(args[0]));
+			return 1;
+		}
+	}
 
 	init_universal();
 	// TODO(bill): prevent compiling without a linker
@@ -1825,11 +1833,16 @@ int main(int arg_count, char const **arg_ptr) {
 		}
 		lb_generate_code(&gen);
 
-		if (build_context.build_mode != BuildMode_Object) {
-			i32 linker_stage_exit_count = linker_stage(&gen);
-			if (linker_stage_exit_count != 0) {
-				return linker_stage_exit_count;
+		switch (build_context.build_mode) {
+		case BuildMode_Executable:
+		case BuildMode_DynamicLibrary:
+			{
+				i32 linker_stage_exit_count = linker_stage(&gen);
+				if (linker_stage_exit_count != 0) {
+					return linker_stage_exit_count;
+				}
 			}
+			break;
 		}
 
 		if (build_context.show_timings) {