From 1f5381512a39614d5129b1ebd1ec256a702e767e Mon Sep 17 00:00:00 2001 From: Bruno Kirschner Date: Thu, 25 Jul 2019 14:50:26 +0200 Subject: [PATCH 1/2] Add missing bracers in classify_arg_ty(). The calculation of required registerd in classify_arg_ty() has a special case for any arguments greater than 32 bits but less than 128 bits in size. The related calculation missed a pair of bracers and therefore always returned a result of one required register per argument bit. --- src/librustc_target/abi/call/xtensa.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_target/abi/call/xtensa.rs b/src/librustc_target/abi/call/xtensa.rs index 191470bd105a3..f0729dac703d9 100644 --- a/src/librustc_target/abi/call/xtensa.rs +++ b/src/librustc_target/abi/call/xtensa.rs @@ -29,7 +29,7 @@ fn classify_arg_ty(arg: &mut ArgType<'_, Ty>, xlen: u64, remaining_gpr: &mut 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; + required_gpr = (arg_size.bits() + (xlen - 1)) / xlen; } if required_gpr > *remaining_gpr { From 28f3d6f75c31dd5c79110b6cdbc5713eafca3904 Mon Sep 17 00:00:00 2001 From: Bruno Kirschner Date: Thu, 25 Jul 2019 15:21:54 +0200 Subject: [PATCH 2/2] Pass big aggregated arguments indirectly. Ensures that arguments of any type can be passed through `classify_arg_ty()`. Previously any aggregated argument with a size above the maximum of `MAX_ARG_IN_REGS_SIZE` triggered the `stack_required` assertion. The reason was that that the flag directly depends on the calculated amount of required registered which is not determined if a given argument is bigger than the expected maximum of `MAX_ARG_IN_REGS_SIZE`. --- src/librustc_target/abi/call/xtensa.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/librustc_target/abi/call/xtensa.rs b/src/librustc_target/abi/call/xtensa.rs index f0729dac703d9..6a46b8a547141 100644 --- a/src/librustc_target/abi/call/xtensa.rs +++ b/src/librustc_target/abi/call/xtensa.rs @@ -20,18 +20,22 @@ fn classify_arg_ty(arg: &mut ArgType<'_, Ty>, xlen: u64, remaining_gpr: &mut // according to the ABI. 2*XLen-aligned varargs are passed in "aligned" // register pairs, so may consume 3 registers. - let mut stack_required = false; let arg_size = arg.layout.size; - let alignment = arg.layout.details.align.abi; - + 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;