From 3227f921e74d0d03424aa16b8ce2c246b7afcb6f Mon Sep 17 00:00:00 2001 From: Randall Spangler Date: Mon, 23 Feb 2015 12:25:32 -0800 Subject: cortex-m0: Fix branch from 64-bit signed to unsigned divide We put each assembly function in its own section. So the sections for 64-bit signed and unsigned divide end up too far apart for b (8-bit delta) or b (11-bit delta). Instead, use bl, which has no such limit. This is a little less efficient in the case where numerator and denominator are both positive, but equivalent if either or both is negative, and is far outweighed by the cost of the unsigned divide itself. The other alternative would be to put both uldivmod and ldivmod in the same section. However, we're often tight on code size on cortex-M0 parts, so that's less desirable. BUG=chrome-os-partner:26126 BRANCH=minnie TEST=add the following function static int command_divtest(int argc, char **argv) { int64_t a, b, c; char *e; if (argc < 2) return EC_ERROR_PARAM_COUNT; a = strtoi(argv[1], &e, 0); b = strtoi(argv[2], &e, 0); c = a / b; ccprintf("%d / %d = %d\n", (int)a, (int)b, (int)c); return EC_SUCCESS; } DECLARE_CONSOLE_COMMAND(dt, command_divtest, "a b", "Divide test", NULL); and test with divides in all 4 quadrants (+/- 20 divided by +/- 5, for example) Change-Id: I2a5e49c4534044c2f509e325f8dd6bdf10b544c4 Signed-off-by: Randall Spangler Reviewed-on: https://chromium-review.googlesource.com/252243 Reviewed-by: Alec Berg --- core/cortex-m0/ldivmod.S | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/cortex-m0/ldivmod.S b/core/cortex-m0/ldivmod.S index 48ebdfcc65..853d85b0d2 100644 --- a/core/cortex-m0/ldivmod.S +++ b/core/cortex-m0/ldivmod.S @@ -73,8 +73,12 @@ L_neg_both: L_num_pos: cmp r3, #0 - bge __aeabi_uldivmod + blt L_den_neg + push {r4, lr} + bl __aeabi_uldivmod @ offset too big for b / bge + pop {r4, pc} +L_den_neg: push {r4, lr} movs r4, #0 @ den = -den rsbs r2, r2, #0 -- cgit v1.2.1