forked from rust-lang/rust
-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request rust-lang#12 from chocol4te/xtensa_1.39
Update to 1.39.0
- Loading branch information
Showing
10 changed files
with
328 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
// reference: https://github.com/espressif/clang-xtensa/commit/6fb488d2553f06029e6611cf81c6efbd45b56e47#diff-aa74ae1e1ab6b7149789237edb78e688R8450 | ||
|
||
use crate::abi::call::{ArgType, FnType, Reg, Uniform}; | ||
|
||
const NUM_ARG_GPR: u64 = 6; | ||
const MAX_ARG_IN_REGS_SIZE: u64 = 4 * 32; | ||
// const MAX_ARG_DIRECT_SIZE: u64 = MAX_ARG_IN_REGS_SIZE; | ||
const MAX_RET_IN_REGS_SIZE: u64 = 2 * 32; | ||
|
||
fn classify_ret_ty<Ty>(arg: &mut ArgType<'_, Ty>, xlen: u64) { | ||
// The rules for return and argument types are the same, so defer to | ||
// classifyArgumentType. | ||
classify_arg_ty(arg, xlen, &mut 2); // two as max return size | ||
} | ||
|
||
fn classify_arg_ty<Ty>(arg: &mut ArgType<'_, Ty>, xlen: u64, remaining_gpr: &mut u64) { | ||
// Determine the number of GPRs needed to pass the current argument | ||
// according to the ABI. 2*XLen-aligned varargs are passed in "aligned" | ||
// register pairs, so may consume 3 registers. | ||
|
||
let arg_size = arg.layout.size; | ||
if arg_size.bits() > MAX_ARG_IN_REGS_SIZE { | ||
arg.make_indirect(); | ||
return; | ||
} | ||
|
||
let alignment = arg.layout.details.align.abi; | ||
let mut required_gpr = 1u64; // at least one per arg | ||
|
||
if alignment.bits() == 2 * xlen { | ||
required_gpr = 2 + (*remaining_gpr % 2); | ||
} else if arg_size.bits() > xlen && arg_size.bits() <= MAX_ARG_IN_REGS_SIZE { | ||
required_gpr = (arg_size.bits() + (xlen - 1)) / xlen; | ||
} | ||
|
||
let mut stack_required = false; | ||
if required_gpr > *remaining_gpr { | ||
stack_required = true; | ||
required_gpr = *remaining_gpr; | ||
} | ||
*remaining_gpr -= required_gpr; | ||
|
||
// if a value can fit in a reg and the | ||
// stack is not required, extend | ||
if !arg.layout.is_aggregate() { | ||
// non-aggregate types | ||
if arg_size.bits() < xlen && !stack_required { | ||
arg.extend_integer_width_to(xlen); | ||
} | ||
} else if arg_size.bits() as u64 <= MAX_ARG_IN_REGS_SIZE { | ||
// aggregate types | ||
// Aggregates which are <= 4*32 will be passed in registers if possible, | ||
// so coerce to integers. | ||
|
||
// Use a single XLen int if possible, 2*XLen if 2*XLen alignment is | ||
// required, and a 2-element XLen array if only XLen alignment is | ||
// required. | ||
// if alignment == 2 * xlen { | ||
// arg.extend_integer_width_to(xlen * 2); | ||
// } else { | ||
// arg.extend_integer_width_to(arg_size + (xlen - 1) / xlen); | ||
// } | ||
if alignment.bits() == 2 * xlen { | ||
arg.cast_to(Uniform { unit: Reg::i64(), total: arg_size }); | ||
} else { | ||
//FIXME array type - this should be a homogenous array type | ||
// arg.extend_integer_width_to(arg_size + (xlen - 1) / xlen); | ||
} | ||
} else { | ||
// if we get here the stack is required | ||
assert!(stack_required); | ||
arg.make_indirect(); | ||
} | ||
|
||
// if arg_size as u64 <= MAX_ARG_IN_REGS_SIZE { | ||
// let align = arg.layout.align.abi.bytes(); | ||
// let total = arg.layout.size; | ||
// arg.cast_to(Uniform { | ||
// unit: if align <= 4 { Reg::i32() } else { Reg::i64() }, | ||
// total | ||
// }); | ||
// return; | ||
// } | ||
} | ||
|
||
pub fn compute_abi_info<Ty>(fty: &mut FnType<'_, Ty>, xlen: u64) { | ||
if !fty.ret.is_ignore() { | ||
classify_ret_ty(&mut fty.ret, xlen); | ||
} | ||
|
||
let return_indirect = | ||
fty.ret.layout.size.bits() > MAX_RET_IN_REGS_SIZE || fty.ret.is_indirect(); | ||
|
||
let mut remaining_gpr = if return_indirect { NUM_ARG_GPR - 1 } else { NUM_ARG_GPR }; | ||
|
||
for arg in &mut fty.args { | ||
if arg.is_ignore() { | ||
continue; | ||
} | ||
classify_arg_ty(arg, xlen, &mut remaining_gpr); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
use crate::spec::{abi::Abi, LinkerFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; | ||
// use crate::spec::abi::Abi; | ||
|
||
pub fn target() -> TargetResult { | ||
Ok(Target { | ||
llvm_target: "xtensa-none-elf".to_string(), | ||
target_endian: "little".to_string(), | ||
target_pointer_width: "32".to_string(), | ||
target_c_int_width: "32".to_string(), | ||
data_layout: "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-f64:64-a:0:32-n32".to_string(), | ||
arch: "xtensa".to_string(), | ||
target_os: "none".to_string(), | ||
target_env: String::new(), | ||
target_vendor: String::new(), | ||
linker_flavor: LinkerFlavor::Gcc, | ||
|
||
options: TargetOptions { | ||
executables: true, | ||
cpu: "esp32".to_string(), | ||
// The LLVM backend currently can't generate object files. To | ||
// workaround this LLVM generates assembly files which then we feed | ||
// to gcc to get object files. For this reason we have a hard | ||
// dependency on this specific gcc. | ||
// asm_args: vec!["-mcpu=esp32".to_string()], | ||
linker: Some("xtensa-esp32-elf-gcc".to_string()), | ||
no_integrated_as: true, | ||
|
||
max_atomic_width: Some(32), | ||
atomic_cas: true, | ||
|
||
// Because these devices have very little resources having an | ||
// unwinder is too onerous so we default to "abort" because the | ||
// "unwind" strategy is very rare. | ||
panic_strategy: PanicStrategy::Abort, | ||
|
||
// Similarly, one almost always never wants to use relocatable | ||
// code because of the extra costs it involves. | ||
relocation_model: "static".to_string(), | ||
|
||
// Right now we invoke an external assembler and this isn't | ||
// compatible with multiple codegen units, and plus we probably | ||
// don't want to invoke that many gcc instances. | ||
default_codegen_units: Some(1), | ||
|
||
// Since MSP430 doesn't meaningfully support faulting on illegal | ||
// instructions, LLVM generates a call to abort() function instead | ||
// of a trap instruction. Such calls are 4 bytes long, and that is | ||
// too much overhead for such small target. | ||
trap_unreachable: false, | ||
|
||
// See the thumb_base.rs file for an explanation of this value | ||
emit_debug_gdb_scripts: false, | ||
|
||
abi_blacklist: vec![ | ||
Abi::Stdcall, | ||
Abi::Fastcall, | ||
Abi::Vectorcall, | ||
Abi::Thiscall, | ||
Abi::Win64, | ||
Abi::SysV64, | ||
], | ||
|
||
..Default::default() | ||
}, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
use crate::spec::{abi::Abi, LinkerFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; | ||
// use crate::spec::abi::Abi; | ||
|
||
pub fn target() -> TargetResult { | ||
Ok(Target { | ||
llvm_target: "xtensa-none-elf".to_string(), | ||
target_endian: "little".to_string(), | ||
target_pointer_width: "32".to_string(), | ||
target_c_int_width: "32".to_string(), | ||
data_layout: "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-f64:64-a:0:32-n32".to_string(), | ||
arch: "xtensa".to_string(), | ||
target_os: "none".to_string(), | ||
target_env: String::new(), | ||
target_vendor: String::new(), | ||
linker_flavor: LinkerFlavor::Gcc, | ||
|
||
options: TargetOptions { | ||
executables: true, | ||
cpu: "esp8266".to_string(), | ||
// The LLVM backend currently can't generate object files. To | ||
// workaround this LLVM generates assembly files which then we feed | ||
// to gcc to get object files. For this reason we have a hard | ||
// dependency on this specific gcc. | ||
// asm_args: vec!["-mcpu=esp8266".to_string()], | ||
linker: Some("xtensa-esp32-elf-gcc".to_string()), | ||
no_integrated_as: true, | ||
|
||
max_atomic_width: Some(32), | ||
atomic_cas: true, | ||
|
||
// Because these devices have very little resources having an | ||
// unwinder is too onerous so we default to "abort" because the | ||
// "unwind" strategy is very rare. | ||
panic_strategy: PanicStrategy::Abort, | ||
|
||
// Similarly, one almost always never wants to use relocatable | ||
// code because of the extra costs it involves. | ||
relocation_model: "static".to_string(), | ||
|
||
// Right now we invoke an external assembler and this isn't | ||
// compatible with multiple codegen units, and plus we probably | ||
// don't want to invoke that many gcc instances. | ||
default_codegen_units: Some(1), | ||
|
||
// Since MSP430 doesn't meaningfully support faulting on illegal | ||
// instructions, LLVM generates a call to abort() function instead | ||
// of a trap instruction. Such calls are 4 bytes long, and that is | ||
// too much overhead for such small target. | ||
trap_unreachable: false, | ||
|
||
// See the thumb_base.rs file for an explanation of this value | ||
emit_debug_gdb_scripts: false, | ||
|
||
abi_blacklist: vec![ | ||
Abi::Stdcall, | ||
Abi::Fastcall, | ||
Abi::Vectorcall, | ||
Abi::Thiscall, | ||
Abi::Win64, | ||
Abi::SysV64, | ||
], | ||
|
||
..Default::default() | ||
}, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
use crate::spec::{abi::Abi, LinkerFlavor, PanicStrategy, Target, TargetOptions, TargetResult}; | ||
// use crate::spec::abi::Abi; | ||
|
||
pub fn target() -> TargetResult { | ||
Ok(Target { | ||
llvm_target: "xtensa-none-elf".to_string(), | ||
target_endian: "little".to_string(), | ||
target_pointer_width: "32".to_string(), | ||
target_c_int_width: "32".to_string(), | ||
data_layout: "e-m:e-p:32:32-i1:8:32-i8:8:32-i16:16:32-i64:64-f64:64-a:0:32-n32".to_string(), | ||
arch: "xtensa".to_string(), | ||
target_os: "none".to_string(), | ||
target_env: String::new(), | ||
target_vendor: String::new(), | ||
linker_flavor: LinkerFlavor::Gcc, | ||
|
||
options: TargetOptions { | ||
executables: true, | ||
|
||
// The LLVM backend currently can't generate object files. To | ||
// workaround this LLVM generates assembly files which then we feed | ||
// to gcc to get object files. For this reason we have a hard | ||
// dependency on this specific gcc. | ||
// asm_args: vec!["-mcpu=generic".to_string()], | ||
linker: Some("xtensa-esp32-elf-gcc".to_string()), | ||
no_integrated_as: true, | ||
|
||
max_atomic_width: Some(32), | ||
atomic_cas: true, | ||
|
||
// Because these devices have very little resources having an | ||
// unwinder is too onerous so we default to "abort" because the | ||
// "unwind" strategy is very rare. | ||
panic_strategy: PanicStrategy::Abort, | ||
|
||
// Similarly, one almost always never wants to use relocatable | ||
// code because of the extra costs it involves. | ||
relocation_model: "static".to_string(), | ||
|
||
// Right now we invoke an external assembler and this isn't | ||
// compatible with multiple codegen units, and plus we probably | ||
// don't want to invoke that many gcc instances. | ||
default_codegen_units: Some(1), | ||
|
||
// Since MSP430 doesn't meaningfully support faulting on illegal | ||
// instructions, LLVM generates a call to abort() function instead | ||
// of a trap instruction. Such calls are 4 bytes long, and that is | ||
// too much overhead for such small target. | ||
trap_unreachable: false, | ||
|
||
// See the thumb_base.rs file for an explanation of this value | ||
emit_debug_gdb_scripts: false, | ||
|
||
abi_blacklist: vec![ | ||
Abi::Stdcall, | ||
Abi::Fastcall, | ||
Abi::Vectorcall, | ||
Abi::Thiscall, | ||
Abi::Win64, | ||
Abi::SysV64, | ||
], | ||
|
||
..Default::default() | ||
}, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters