528 lines
28 KiB
Diff
528 lines
28 KiB
Diff
--- a/src/trans/codegen_c.cpp
|
|
+++ b/src/trans/codegen_c.cpp
|
|
@@ -236,6 +236,7 @@
|
|
const ::MIR::TypeResolve* m_mir_res = nullptr;
|
|
|
|
Compiler m_compiler = Compiler::Gcc;
|
|
+ bool m_cc65 = false;
|
|
struct {
|
|
bool emulated_i128 = false;
|
|
bool disallow_empty_structs = false;
|
|
@@ -254,6 +255,8 @@
|
|
{
|
|
ASSERT_BUG(Span(), m_of.is_open(), "Failed to open `" << m_outfile_path_c << "` for writing");
|
|
m_options.emulated_i128 = Target_GetCurSpec().m_backend_c.m_emulated_i128;
|
|
+ m_cc65 = Target_GetCurSpec().m_backend_c.m_c_compiler == "cl65"
|
|
+ || Target_GetCurSpec().m_backend_c.m_c_compiler == "cc65";
|
|
switch(Target_GetCurSpec().m_backend_c.m_codegen_mode)
|
|
{
|
|
case CodegenMode::Gnu11:
|
|
@@ -287,13 +290,13 @@
|
|
switch(m_compiler)
|
|
{
|
|
case Compiler::Gcc:
|
|
- m_of
|
|
- << "#include <stdatomic.h>\n" // atomic_*
|
|
- << "#include <stdlib.h>\n" // abort
|
|
- << "#include <string.h>\n" // mem*
|
|
- << "#include <math.h>\n" // round, ...
|
|
- << "#include <setjmp.h>\n" // setjmp/jmp_buf
|
|
- ;
|
|
+ m_of << "#include <stdlib.h>\n" // abort
|
|
+ << "#include <string.h>\n" // mem*
|
|
+ << "#include <setjmp.h>\n"; // setjmp/jmp_buf
|
|
+ if( !m_cc65 ) {
|
|
+ m_of << "#include <stdatomic.h>\n" // atomic_*
|
|
+ << "#include <math.h>\n"; // round, ...
|
|
+ }
|
|
break;
|
|
case Compiler::Msvc:
|
|
m_of
|
|
@@ -329,16 +332,19 @@
|
|
;
|
|
}
|
|
m_of
|
|
- << "static inline size_t ALIGN_TO(size_t s, size_t a) { return (s + a-1) / a * a; }\n"
|
|
+ << "static " << (m_cc65 ? "" : "inline ") << "size_t ALIGN_TO(size_t s, size_t a) { return (s + a-1) / a * a; }\n"
|
|
<< "\n"
|
|
;
|
|
switch(m_compiler)
|
|
{
|
|
case Compiler::Gcc:
|
|
- m_of
|
|
- << "extern void _Unwind_Resume(void) __attribute__((noreturn));\n"
|
|
- << "#define ALIGNOF(t) __alignof__(t)\n"
|
|
- ;
|
|
+ if( m_cc65 ) {
|
|
+ m_of << "static void _Unwind_Resume(void) { }\n";
|
|
+ }
|
|
+ else {
|
|
+ m_of << "extern void _Unwind_Resume(void) __attribute__((noreturn));\n";
|
|
+ }
|
|
+ m_of << (m_cc65 ? "#define ALIGNOF(t) 1\n" : "#define ALIGNOF(t) __alignof__(t)\n");
|
|
break;
|
|
case Compiler::Msvc:
|
|
m_of
|
|
@@ -352,12 +358,11 @@
|
|
switch (m_compiler)
|
|
{
|
|
case Compiler::Gcc:
|
|
- m_of
|
|
- << "extern __thread jmp_buf* mrustc_panic_target;\n"
|
|
- << "extern __thread void* mrustc_panic_value;\n"
|
|
- ;
|
|
+ m_of << "extern " << (m_cc65 ? "" : "__thread ") << "jmp_buf* mrustc_panic_target;\n"
|
|
+ << "extern " << (m_cc65 ? "" : "__thread ") << "void* mrustc_panic_value;\n";
|
|
// 64-bit bit ops (gcc intrinsics)
|
|
- m_of
|
|
+ if( !m_cc65 ) {
|
|
+ m_of
|
|
<< "static inline uint64_t __builtin_clz64(uint64_t v) {\n"
|
|
<< "\treturn ( (v >> 32) != 0 ? __builtin_clz(v>>32) : 32 + __builtin_clz(v));\n"
|
|
<< "}\n"
|
|
@@ -365,10 +370,10 @@
|
|
<< "\treturn ((v&0xFFFFFFFF) == 0 ? __builtin_ctz(v>>32) + 32 : __builtin_ctz(v));\n"
|
|
<< "}\n"
|
|
;
|
|
- // Atomic hackery
|
|
- for(int sz = 8; sz <= 64; sz *= 2)
|
|
- {
|
|
- m_of
|
|
+ // Atomic hackery
|
|
+ for(int sz = 8; sz <= 64; sz *= 2)
|
|
+ {
|
|
+ m_of
|
|
<< "static inline uint"<<sz<<"_t __mrustc_atomicloop"<<sz<<"(volatile uint"<<sz<<"_t* slot, uint"<<sz<<"_t param, int ordering, uint"<<sz<<"_t (*cb)(uint"<<sz<<"_t, uint"<<sz<<"_t)) {"
|
|
<< " int ordering_load = (ordering == memory_order_release || ordering == memory_order_acq_rel ? memory_order_relaxed : ordering);" // If Release, Load with Relaxed
|
|
<< " for(;;) {"
|
|
@@ -376,7 +381,8 @@
|
|
<< " if( atomic_compare_exchange_strong_explicit((_Atomic uint"<<sz<<"_t*)slot, &v, cb(v, param), ordering, ordering_load) ) return v;"
|
|
<< " }"
|
|
<< "}\n"
|
|
- ;
|
|
+ ;
|
|
+ }
|
|
}
|
|
break;
|
|
case Compiler::Msvc:
|
|
@@ -600,8 +606,10 @@
|
|
break;
|
|
}
|
|
|
|
- if( m_options.emulated_i128 )
|
|
+ if( !m_cc65 )
|
|
{
|
|
+ if( m_options.emulated_i128 )
|
|
+ {
|
|
m_of
|
|
<< "typedef struct { uint64_t lo, hi; } uint128_t;\n"
|
|
<< "typedef struct { uint64_t lo, hi; } int128_t;\n"
|
|
@@ -749,9 +757,9 @@
|
|
<< "static inline uint128_t int128_to_uint128(int128_t a) { return make128_raw(a.lo, a.hi); }\n"
|
|
<< "static inline int128_t uint128_to_int128(uint128_t a) { return make128s_raw(a.lo, a.hi); }\n"
|
|
;
|
|
- }
|
|
- else
|
|
- {
|
|
+ }
|
|
+ else
|
|
+ {
|
|
// GCC-only
|
|
m_of
|
|
<< "typedef unsigned __int128 uint128_t;\n"
|
|
@@ -768,27 +776,29 @@
|
|
<< "\treturn (v == 0 ? 128 : ((v&0xFFFFFFFFFFFFFFFF) == 0 ? __builtin_ctz64(v>>64) + 64 : __builtin_ctz64(v)));\n"
|
|
<< "}\n"
|
|
;
|
|
+ }
|
|
}
|
|
|
|
// Common helpers
|
|
m_of
|
|
<< "\n"
|
|
- << "static inline int slice_cmp(SLICE_PTR l, SLICE_PTR r) {\n"
|
|
+ << "static " << (m_cc65 ? "" : "inline ") << "int slice_cmp(SLICE_PTR l, SLICE_PTR r) {\n"
|
|
<< "\tint rv = memcmp(l.PTR, r.PTR, l.META < r.META ? l.META : r.META);\n"
|
|
<< "\tif(rv != 0) return rv;\n"
|
|
<< "\tif(l.META < r.META) return -1;\n"
|
|
<< "\tif(l.META > r.META) return 1;\n"
|
|
<< "\treturn 0;\n"
|
|
<< "}\n"
|
|
- << "static inline SLICE_PTR make_sliceptr(void* ptr, size_t s) { SLICE_PTR rv = { ptr, s }; return rv; }\n"
|
|
- << "static inline TRAITOBJ_PTR make_traitobjptr(void* ptr, void* vt) { TRAITOBJ_PTR rv = { ptr, vt }; return rv; }\n"
|
|
+ << "static " << (m_cc65 ? "" : "inline ") << "SLICE_PTR make_sliceptr(void* ptr, size_t s) { SLICE_PTR rv; rv.PTR = ptr; rv.META = s; return rv; }\n"
|
|
+ << "static " << (m_cc65 ? "" : "inline ") << "TRAITOBJ_PTR make_traitobjptr(void* ptr, void* vt) { TRAITOBJ_PTR rv; rv.PTR = ptr; rv.META = vt; return rv; }\n"
|
|
<< "\n"
|
|
- << "static inline size_t mrustc_max(size_t a, size_t b) { return a < b ? b : a; }\n"
|
|
- << "static inline void noop_drop(tUNIT *p) { }\n"
|
|
+ << "static " << (m_cc65 ? "" : "inline ") << "size_t mrustc_max(size_t a, size_t b) { return a < b ? b : a; }\n"
|
|
+ << "static " << (m_cc65 ? "" : "inline ") << "void noop_drop(tUNIT *p) { }\n"
|
|
<< "\n"
|
|
// A linear (fast-fail) search of a list of strings
|
|
- << "static inline size_t mrustc_string_search_linear(SLICE_PTR val, size_t count, SLICE_PTR* options) {\n"
|
|
- << "\tfor(size_t i = 0; i < count; i ++) {\n"
|
|
+ << "static " << (m_cc65 ? "" : "inline ") << "size_t mrustc_string_search_linear(SLICE_PTR val, size_t count, SLICE_PTR* options) {\n"
|
|
+ << "\tsize_t i;\n"
|
|
+ << "\tfor(i = 0; i < count; i ++) {\n"
|
|
<< "\t\tint cmp = slice_cmp(val, options[i]);\n"
|
|
<< "\t\tif(cmp < 0) break;\n"
|
|
<< "\t\tif(cmp == 0) return i;\n"
|
|
@@ -797,38 +807,40 @@
|
|
<< "}\n"
|
|
// Map of reversed nibbles 0 1 2 3 4 5 6 7 8 9 10 11 12 14 15
|
|
<< "static const uint8_t __mrustc_revmap[16] = { 0, 8, 4,12, 2,10, 6,14, 1, 9, 5,13, 3, 7,15};\n"
|
|
- << "static inline uint8_t __mrustc_bitrev8(uint8_t v) { if(v==0||v==0xFF) return v; return __mrustc_revmap[v>>4]|(__mrustc_revmap[v&15]<<4); }\n"
|
|
- << "static inline uint16_t __mrustc_bitrev16(uint16_t v) { if(v==0) return 0; return ((uint16_t)__mrustc_bitrev8(v>>8))|((uint16_t)__mrustc_bitrev8(v)<<8); }\n"
|
|
- << "static inline uint32_t __mrustc_bitrev32(uint32_t v) { if(v==0) return 0; return ((uint32_t)__mrustc_bitrev16(v>>16))|((uint32_t)__mrustc_bitrev16(v)<<16); }\n"
|
|
- << "static inline uint64_t __mrustc_bitrev64(uint64_t v) { if(v==0) return 0; return ((uint64_t)__mrustc_bitrev32(v>>32))|((uint64_t)__mrustc_bitrev32(v)<<32); }\n"
|
|
+ << "static " << (m_cc65 ? "" : "inline ") << "uint8_t __mrustc_bitrev8(uint8_t v) { if(v==0||v==0xFF) return v; return __mrustc_revmap[v>>4]|(__mrustc_revmap[v&15]<<4); }\n"
|
|
+ << "static " << (m_cc65 ? "" : "inline ") << "uint16_t __mrustc_bitrev16(uint16_t v) { if(v==0) return 0; return ((uint16_t)__mrustc_bitrev8(v>>8))|((uint16_t)__mrustc_bitrev8(v)<<8); }\n"
|
|
+ << "static " << (m_cc65 ? "" : "inline ") << "uint32_t __mrustc_bitrev32(uint32_t v) { if(v==0) return 0; return ((uint32_t)__mrustc_bitrev16(v>>16))|((uint32_t)__mrustc_bitrev16(v)<<16); }\n"
|
|
// TODO: 128
|
|
;
|
|
- if( m_options.emulated_i128 )
|
|
- {
|
|
- m_of << "static inline uint128_t __mrustc_bitrev128(uint128_t v) { uint128_t rv = { __mrustc_bitrev64(v.hi), __mrustc_bitrev64(v.lo) }; return rv; }\n";
|
|
- }
|
|
- else
|
|
- {
|
|
- m_of << "static inline uint128_t __mrustc_bitrev128(uint128_t v) {"
|
|
- << " if(v==0) return 0;"
|
|
- << " uint128_t rv = ((uint128_t)__mrustc_bitrev64(v>>64))|((uint128_t)__mrustc_bitrev64(v)<<64);"
|
|
- << " return rv;"
|
|
- << " }\n"
|
|
- ;
|
|
+ if( !m_cc65 ) {
|
|
+ m_of << "static inline uint64_t __mrustc_bitrev64(uint64_t v) { if(v==0) return 0; return ((uint64_t)__mrustc_bitrev32(v>>32))|((uint64_t)__mrustc_bitrev32(v)<<32); }\n";
|
|
+ if( m_options.emulated_i128 )
|
|
+ {
|
|
+ m_of << "static inline uint128_t __mrustc_bitrev128(uint128_t v) { uint128_t rv = { __mrustc_bitrev64(v.hi), __mrustc_bitrev64(v.lo) }; return rv; }\n";
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ m_of << "static inline uint128_t __mrustc_bitrev128(uint128_t v) {"
|
|
+ << " if(v==0) return 0;"
|
|
+ << " uint128_t rv = ((uint128_t)__mrustc_bitrev64(v>>64))|((uint128_t)__mrustc_bitrev64(v)<<64);"
|
|
+ << " return rv;"
|
|
+ << " }\n"
|
|
+ ;
|
|
+ }
|
|
}
|
|
- for(int sz = 8; sz <= 64; sz *= 2)
|
|
+ for(int sz = 8; sz <= (m_cc65 ? 32 : 64); sz *= 2)
|
|
{
|
|
m_of
|
|
- << "static inline uint"<<sz<<"_t __mrustc_op_umax"<<sz<<"(uint"<<sz<<"_t a, uint"<<sz<<"_t b) { return (a > b ? a : b); }\n"
|
|
- << "static inline uint"<<sz<<"_t __mrustc_op_umin"<<sz<<"(uint"<<sz<<"_t a, uint"<<sz<<"_t b) { return (a < b ? a : b); }\n"
|
|
- << "static inline uint"<<sz<<"_t __mrustc_op_imax"<<sz<<"(uint"<<sz<<"_t a, uint"<<sz<<"_t b) { return ((int"<<sz<<"_t)a > (int"<<sz<<"_t)b ? a : b); }\n"
|
|
- << "static inline uint"<<sz<<"_t __mrustc_op_imin"<<sz<<"(uint"<<sz<<"_t a, uint"<<sz<<"_t b) { return ((int"<<sz<<"_t)a < (int"<<sz<<"_t)b ? a : b); }\n"
|
|
- << "static inline uint"<<sz<<"_t __mrustc_op_and_not"<<sz<<"(uint"<<sz<<"_t a, uint"<<sz<<"_t b) { return ~(a & b); }\n"
|
|
+ << "static " << (m_cc65 ? "" : "inline ") << "uint"<<sz<<"_t __mrustc_op_umax"<<sz<<"(uint"<<sz<<"_t a, uint"<<sz<<"_t b) { return (a > b ? a : b); }\n"
|
|
+ << "static " << (m_cc65 ? "" : "inline ") << "uint"<<sz<<"_t __mrustc_op_umin"<<sz<<"(uint"<<sz<<"_t a, uint"<<sz<<"_t b) { return (a < b ? a : b); }\n"
|
|
+ << "static " << (m_cc65 ? "" : "inline ") << "uint"<<sz<<"_t __mrustc_op_imax"<<sz<<"(uint"<<sz<<"_t a, uint"<<sz<<"_t b) { return ((int"<<sz<<"_t)a > (int"<<sz<<"_t)b ? a : b); }\n"
|
|
+ << "static " << (m_cc65 ? "" : "inline ") << "uint"<<sz<<"_t __mrustc_op_imin"<<sz<<"(uint"<<sz<<"_t a, uint"<<sz<<"_t b) { return ((int"<<sz<<"_t)a < (int"<<sz<<"_t)b ? a : b); }\n"
|
|
+ << "static " << (m_cc65 ? "" : "inline ") << "uint"<<sz<<"_t __mrustc_op_and_not"<<sz<<"(uint"<<sz<<"_t a, uint"<<sz<<"_t b) { return ~(a & b); }\n"
|
|
;
|
|
}
|
|
|
|
// Float16 and Float128
|
|
- m_of
|
|
+ if( !m_cc65 ) m_of
|
|
<< "typedef struct f16 { uint16_t v; } f16;\n"
|
|
<< "static f16 f16_disabled(){ abort(); }\n"
|
|
<< "static int f16_cmp(f16 a, f16 b){ abort(); }\n"
|
|
@@ -850,7 +862,7 @@
|
|
if( out_ty == CodegenOutput::Executable )
|
|
{
|
|
// TODO: Define this function in MIR?
|
|
- m_of << "int main(int argc, const char* argv[]) {\n";
|
|
+ m_of << "int main(int argc, " << (m_cc65 ? "" : "const ") << "char* argv[]) {\n";
|
|
auto c_start_path = m_resolve.m_crate.get_lang_item_path_opt("mrustc-start");
|
|
if( c_start_path == ::HIR::SimplePath() )
|
|
{
|
|
@@ -883,14 +895,12 @@
|
|
{
|
|
if( m_compiler == Compiler::Gcc )
|
|
{
|
|
- m_of
|
|
- << "__thread jmp_buf* mrustc_panic_target;\n"
|
|
- << "__thread void* mrustc_panic_value;\n"
|
|
- ;
|
|
+ m_of << (m_cc65 ? "" : "__thread ") << "jmp_buf* mrustc_panic_target;\n"
|
|
+ << (m_cc65 ? "" : "__thread ") << "void* mrustc_panic_value;\n";
|
|
}
|
|
|
|
// Allocator/panic shims
|
|
- if( TARGETVER_LEAST_1_29 )
|
|
+ if( TARGETVER_LEAST_1_29 && !m_cc65 )
|
|
{
|
|
// If #[global_allocator] present, use `__rg_`
|
|
const char* alloc_prefix = "__rdl_";
|
|
@@ -1027,9 +1037,18 @@
|
|
{
|
|
// Bind `panic_impl` lang item to the item tagged with `panic_implementation`
|
|
m_of << "uint32_t panic_impl(uintptr_t payload) {";
|
|
- const auto& panic_impl_path = m_crate.get_lang_item_path(Span(), "mrustc-panic_implementation");
|
|
- m_of << "extern uint32_t " << Trans_Mangle(panic_impl_path) << "(uintptr_t payload);";
|
|
- m_of << "return " << Trans_Mangle(panic_impl_path) << "(payload);";
|
|
+ if( m_cc65 ) {
|
|
+ // cc65 builds are freestanding and use panic=abort. The
|
|
+ // modern panic handler ABI is not representable by the
|
|
+ // small C runtime, so terminate locally instead of
|
|
+ // importing the host Rust runtime shim.
|
|
+ m_of << "(void)payload; abort(); return 0;";
|
|
+ }
|
|
+ else {
|
|
+ const auto& panic_impl_path = m_crate.get_lang_item_path(Span(), "mrustc-panic_implementation");
|
|
+ m_of << "extern uint32_t " << Trans_Mangle(panic_impl_path) << "(uintptr_t payload);";
|
|
+ m_of << "return " << Trans_Mangle(panic_impl_path) << "(payload);";
|
|
+ }
|
|
m_of << "}\n";
|
|
}
|
|
}
|
|
@@ -1290,6 +1309,9 @@
|
|
else if( getenv("CC") ) {
|
|
args.push_back( getenv("CC") );
|
|
}
|
|
+ else if( m_cc65 ) {
|
|
+ args.push_back("cl65");
|
|
+ }
|
|
else if (system(("command -v " + Target_GetCurSpec().m_backend_c.m_c_compiler + "-gcc" + " >/dev/null 2>&1").c_str()) == 0) {
|
|
args.push_back( Target_GetCurSpec().m_backend_c.m_c_compiler + "-gcc" );
|
|
}
|
|
@@ -1302,21 +1324,23 @@
|
|
{
|
|
args.push_back( a.c_str() );
|
|
}
|
|
- args.push_back("-U_GLIBCXX_ASSERTIONS"); // TODO
|
|
- args.push_back("-Wno-psabi"); // Suppress "note: the ABI for passing parameters with 128-byte alignment has changed in GCC 4.6"
|
|
+ if( !m_cc65 ) {
|
|
+ args.push_back("-U_GLIBCXX_ASSERTIONS"); // TODO
|
|
+ args.push_back("-Wno-psabi"); // Suppress "note: the ABI for passing parameters with 128-byte alignment has changed in GCC 4.6"
|
|
+ }
|
|
switch(opt.opt_level)
|
|
{
|
|
case 0: break;
|
|
case 1:
|
|
- args.push_back("-O1");
|
|
+ args.push_back(m_cc65 ? "-O" : "-O1");
|
|
break;
|
|
case 2:
|
|
//args.push_back("-O2");
|
|
- args.push_back("-O1"); // HACK: Work around mrustc #347 by reducing the optimisation level
|
|
+ args.push_back(m_cc65 ? "-O" : "-O1"); // HACK: Work around mrustc #347 by reducing the optimisation level
|
|
break;
|
|
}
|
|
// HACK: Work around [https://gcc.gnu.org/bugzilla/show_bug.cgi?id=117423] by disabling an optimisation stage
|
|
- if( opt.opt_level > 0 )
|
|
+ if( opt.opt_level > 0 && !m_cc65 )
|
|
{
|
|
args.push_back("-fno-tree-sra");
|
|
}
|
|
@@ -1325,7 +1349,9 @@
|
|
args.push_back("-g");
|
|
}
|
|
// TODO: Why?
|
|
- args.push_back("-fPIC");
|
|
+ if( !m_cc65 ) {
|
|
+ args.push_back("-fPIC");
|
|
+ }
|
|
args.push_back("-o");
|
|
switch(out_ty)
|
|
{
|
|
@@ -1348,35 +1374,38 @@
|
|
{
|
|
args.push_back( a.c_str() );
|
|
}
|
|
- for(const auto& c : ext_crates)
|
|
- {
|
|
- args.push_back(std::string(c) + ".o");
|
|
- }
|
|
- for(const auto& c : ext_crates_dylib)
|
|
- {
|
|
- args.push_back(c);
|
|
- }
|
|
- for(auto l_d : libraries_and_dirs)
|
|
+ if( !m_cc65 )
|
|
{
|
|
- switch(l_d.first)
|
|
+ for(const auto& c : ext_crates)
|
|
{
|
|
- case LinkList::Ty::Directory:
|
|
- args.push_back("-L");
|
|
- args.push_back(l_d.second);
|
|
- break;
|
|
- case LinkList::Ty::Implicit:
|
|
- if (!strncmp(l_d.second, "framework=", strlen("framework="))) {
|
|
- args.push_back("-framework");
|
|
- args.push_back(l_d.second + strlen("framework="));
|
|
- }
|
|
- else {
|
|
- args.push_back("-l");
|
|
+ args.push_back(std::string(c) + ".o");
|
|
+ }
|
|
+ for(const auto& c : ext_crates_dylib)
|
|
+ {
|
|
+ args.push_back(c);
|
|
+ }
|
|
+ for(auto l_d : libraries_and_dirs)
|
|
+ {
|
|
+ switch(l_d.first)
|
|
+ {
|
|
+ case LinkList::Ty::Directory:
|
|
+ args.push_back("-L");
|
|
+ args.push_back(l_d.second);
|
|
+ break;
|
|
+ case LinkList::Ty::Implicit:
|
|
+ if (!strncmp(l_d.second, "framework=", strlen("framework="))) {
|
|
+ args.push_back("-framework");
|
|
+ args.push_back(l_d.second + strlen("framework="));
|
|
+ }
|
|
+ else {
|
|
+ args.push_back("-l");
|
|
+ args.push_back(l_d.second);
|
|
+ }
|
|
+ break;
|
|
+ case LinkList::Ty::Explicit:
|
|
args.push_back(l_d.second);
|
|
+ break;
|
|
}
|
|
- break;
|
|
- case LinkList::Ty::Explicit:
|
|
- args.push_back(l_d.second);
|
|
- break;
|
|
}
|
|
}
|
|
for( const auto& a : Target_GetCurSpec().m_backend_c.m_linker_opts_post )
|
|
@@ -1492,7 +1521,7 @@
|
|
if( getenv("MRUSTC_CCACHE") ) {
|
|
cmd_ss << "ccache ";
|
|
}
|
|
- bool use_arg_file = arg_file_start > 0;
|
|
+ bool use_arg_file = arg_file_start > 0 && !m_cc65;
|
|
if(use_arg_file) {
|
|
command_file_stream.open(command_file);
|
|
ASSERT_BUG(Span(), command_file_stream.is_open(), "Failed to open command file `" << command_file << "` for writing");
|
|
@@ -1671,7 +1700,9 @@
|
|
m_of << "typedef struct "; emit_ctype(ty); m_of << " "; emit_ctype(ty); m_of << ";\n";
|
|
}
|
|
TU_ARMA(Array, te) {
|
|
- m_of << "typedef struct "; emit_ctype(ty); m_of << " "; emit_ctype(ty); m_of << ";\n";
|
|
+ if( !m_cc65 ) {
|
|
+ m_of << "typedef struct "; emit_ctype(ty); m_of << " "; emit_ctype(ty); m_of << ";\n";
|
|
+ }
|
|
}
|
|
TU_ARMA(Path, te) {
|
|
TU_MATCH_HDRA( (te.binding), {)
|
|
@@ -1953,7 +1984,7 @@
|
|
|
|
emit_struct_inner(ty, repr, /*packing_max_align=*/0);
|
|
|
|
- if( repr->size > 0 )
|
|
+ if( repr->size > 0 && !m_cc65 )
|
|
{
|
|
m_of << "typedef char sizeof_assert_"; emit_ctype(ty); m_of << "[ (sizeof("; emit_ctype(ty); m_of << ") == " << repr->size << ") ? 1 : -1 ];\n";
|
|
}
|
|
@@ -2049,7 +2080,7 @@
|
|
|
|
emit_struct_inner(item_ty, repr, item.m_max_field_alignment);
|
|
|
|
- if(repr->size > 0 && repr->size != SIZE_MAX )
|
|
+ if(repr->size > 0 && repr->size != SIZE_MAX && !m_cc65 )
|
|
{
|
|
// TODO: Handle unsized (should check the size of the fixed-size region)
|
|
m_of << "typedef char sizeof_assert_" << Trans_Mangle(p) << "[ (sizeof(struct s_" << Trans_Mangle(p) << ") == " << repr->size << ") ? 1 : -1 ];\n";
|
|
@@ -2076,7 +2107,7 @@
|
|
m_of << "\t"; emit_ctype( repr->fields[i].ty, FMT_CB(ss, ss << "var_" << i;) ); m_of << ";\n";
|
|
}
|
|
m_of << "};\n";
|
|
- if( true && repr->size > 0 )
|
|
+ if( true && repr->size > 0 && !m_cc65 )
|
|
{
|
|
m_of << "typedef char sizeof_assert_" << Trans_Mangle(p) << "[ (sizeof(union u_" << Trans_Mangle(p) << ") == " << repr->size << ") ? 1 : -1 ];\n";
|
|
}
|
|
@@ -2278,7 +2309,9 @@
|
|
m_of << "};\n";
|
|
|
|
size_t exp_size = (repr->size > 0 ? repr->size : (m_options.disallow_empty_structs ? 1 : 0));
|
|
- m_of << "typedef char sizeof_assert_" << Trans_Mangle(p) << "[ (sizeof(struct e_" << Trans_Mangle(p) << ") == " << exp_size << ") ? 1 : -1 ];\n";
|
|
+ if( !m_cc65 ) {
|
|
+ m_of << "typedef char sizeof_assert_" << Trans_Mangle(p) << "[ (sizeof(struct e_" << Trans_Mangle(p) << ") == " << exp_size << ") ? 1 : -1 ];\n";
|
|
+ }
|
|
|
|
m_mir_res = nullptr;
|
|
}
|
|
@@ -4096,9 +4129,18 @@
|
|
m_of << ".PTR";
|
|
}
|
|
TU_ARMA(MakeDst, ve) {
|
|
+ auto meta = metadata_type(ty.data().is_Pointer() ? ty.data().as_Pointer().inner : ty.data().as_Borrow().inner);
|
|
+ if( m_cc65 && (meta == MetadataType::Slice || meta == MetadataType::TraitObject) ) {
|
|
+ // cc65's struct return/pass-by-value ABI is unreliable.
|
|
+ // Build fat pointers in place instead of returning one
|
|
+ // from make_sliceptr/make_traitobjptr.
|
|
+ emit_lvalue(e.dst); m_of << ".PTR = "; emit_param(ve.ptr_val);
|
|
+ m_of << ";\n" << indent;
|
|
+ emit_lvalue(e.dst); m_of << ".META = "; emit_param(ve.meta_val);
|
|
+ break;
|
|
+ }
|
|
emit_lvalue(e.dst);
|
|
m_of << " = ";
|
|
- auto meta = metadata_type(ty.data().is_Pointer() ? ty.data().as_Pointer().inner : ty.data().as_Borrow().inner);
|
|
switch(meta)
|
|
{
|
|
case MetadataType::Slice:
|
|
@@ -4690,7 +4732,7 @@
|
|
if( (*ve)[i] == INT64_MIN )
|
|
m_of << "INT64_MIN";
|
|
else
|
|
- m_of << (*ve)[i] << "ll";
|
|
+ m_of << (*ve)[i] << (m_cc65 ? "l" : "ll");
|
|
m_of << ": "; cb(i); m_of << " break;\n";
|
|
}
|
|
m_of << indent << "\tdefault: "; cb(SIZE_MAX); m_of << "\n";
|
|
@@ -8115,19 +8157,19 @@
|
|
}
|
|
else {
|
|
m_of << c.v.truncate_i64();
|
|
- m_of << "ll";
|
|
+ m_of << (m_cc65 ? "l" : "ll");
|
|
}
|
|
break;
|
|
case ::HIR::CoreType::I128:
|
|
if( m_options.emulated_i128 )
|
|
{
|
|
- m_of << "make128s_raw(" << c.v.get_inner().get_hi() << "ull, " << c.v.get_inner().get_lo() << "ull)";
|
|
+ m_of << "make128s_raw(" << c.v.get_inner().get_hi() << (m_cc65 ? "ul, " : "ull, ") << c.v.get_inner().get_lo() << (m_cc65 ? "ul)" : "ull)");
|
|
}
|
|
else if( c.v.is_i64() && c.v.truncate_i64() != INT64_MIN )
|
|
{
|
|
m_of << "(int128_t)";
|
|
m_of << c.v;
|
|
- m_of << "ll";
|
|
+ m_of << (m_cc65 ? "l" : "ll");
|
|
}
|
|
else
|
|
{
|
|
@@ -8153,17 +8195,17 @@
|
|
break;
|
|
case ::HIR::CoreType::U64:
|
|
case ::HIR::CoreType::Usize:
|
|
- m_of << ::std::hex << "0x" << c.v.truncate_u64() << "ull" << ::std::dec;
|
|
+ m_of << ::std::hex << "0x" << c.v.truncate_u64() << (m_cc65 ? "ul" : "ull") << ::std::dec;
|
|
break;
|
|
case ::HIR::CoreType::U128:
|
|
if( m_options.emulated_i128 )
|
|
{
|
|
- m_of << "make128_raw(" << c.v.get_hi() << "ull, " << c.v.get_lo() << "ull)";
|
|
+ m_of << "make128_raw(" << c.v.get_hi() << (m_cc65 ? "ul, " : "ull, ") << c.v.get_lo() << (m_cc65 ? "ul)" : "ull)");
|
|
}
|
|
else if( c.v.is_u64() )
|
|
{
|
|
m_of << "(uint128_t)";
|
|
- m_of << ::std::hex << "0x" << c.v << "ull" << ::std::dec;
|
|
+ m_of << ::std::hex << "0x" << c.v << (m_cc65 ? "ul" : "ull") << ::std::dec;
|
|
}
|
|
else
|
|
{
|