diff options
author | pbrook <pbrook@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-01-03 23:48:10 +0000 |
---|---|---|
committer | pbrook <pbrook@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-01-03 23:48:10 +0000 |
commit | 25f905c239ab087a017c1c1d393de92f2f1eb301 (patch) | |
tree | e7fbd881338bffa6ed838d87847ff2484257e411 /gcc/config/arm/ieee754-sf.S | |
parent | 5032e5f8188169c7051ab89c4dd15d4280e50de4 (diff) | |
download | gcc-25f905c239ab087a017c1c1d393de92f2f1eb301.tar.gz |
2007-01-03 Paul Brook <paul@codesourcery.com>
Merge from sourcerygxx-4_1.
gcc/
* config/arm/thumb2.md: New file.
* config/arm/elf.h (JUMP_TABLES_IN_TEXT_SECTION): Return True for
Thumb-2.
* config/arm/coff.h (JUMP_TABLES_IN_TEXT_SECTION): Ditto.
* config/arm/aout.h (ASM_OUTPUT_ADDR_VEC_ELT): Add !Thumb-2 assertion.
(ASM_OUTPUT_ADDR_DIFF_ELT): Output Thumb-2 jump tables.
* config/arm/aof.h (ASM_OUTPUT_ADDR_DIFF_ELT): Output Thumb-2 jump
tables.
(ASM_OUTPUT_ADDR_VEC_ELT): Add !Thumb-2 assertion.
* config/arm/ieee754-df.S: Use macros for Thumb-2/Unified asm
comptibility.
* config/arm/ieee754-sf.S: Ditto.
* config/arm/arm.c (thumb_base_register_rtx_p): Rename...
(thumb1_base_register_rtx_p): ... to this.
(thumb_index_register_rtx_p): Rename...
(thumb1_index_register_rtx_p): ... to this.
(thumb_output_function_prologue): Rename...
(thumb1_output_function_prologue): ... to this.
(thumb_legitimate_address_p): Rename...
(thumb1_legitimate_address_p): ... to this.
(thumb_rtx_costs): Rename...
(thumb1_rtx_costs): ... to this.
(thumb_compute_save_reg_mask): Rename...
(thumb1_compute_save_reg_mask): ... to this.
(thumb_final_prescan_insn): Rename...
(thumb1_final_prescan_insn): ... to this.
(thumb_expand_epilogue): Rename...
(thumb1_expand_epilogue): ... to this.
(arm_unwind_emit_stm): Rename...
(arm_unwind_emit_sequence): ... to this.
(thumb2_legitimate_index_p, thumb2_legitimate_address_p,
thumb1_compute_save_reg_mask, arm_dwarf_handle_frame_unspec,
thumb2_index_mul_operand, output_move_vfp, arm_shift_nmem,
arm_save_coproc_regs, thumb_set_frame_pointer, arm_print_condition,
thumb2_final_prescan_insn, thumb2_asm_output_opcode, arm_output_shift,
thumb2_output_casesi): New functions.
(TARGET_DWARF_HANDLE_FRAME_UNSPEC): Define.
(FL_THUMB2, FL_NOTM, FL_DIV, FL_FOR_ARCH6T2, FL_FOR_ARCH7,
FL_FOR_ARCH7A, FL_FOR_ARCH7R, FL_FOR_ARCH7M, ARM_LSL_NAME,
THUMB2_WORK_REGS): Define.
(arm_arch_notm, arm_arch_thumb2, arm_arch_hwdiv, arm_condexec_count,
arm_condexec_mask, arm_condexec_masklen)): New variables.
(all_architectures): Add armv6t2, armv7, armv7a, armv7r and armv7m.
(arm_override_options): Check new CPU capabilities.
Set new architecture flag variables.
(arm_isr_value): Handle v7m interrupt functions.
(user_return_insn): Return 0 for v7m interrupt functions. Handle
Thumb-2.
(const_ok_for_arm): Handle Thumb-2 constants.
(arm_gen_constant): Ditto. Use movw when available.
(arm_function_ok_for_sibcall): Return false for v7m interrupt
functions.
(legitimize_pic_address, arm_call_tls_get_addr): Handle Thumb-2.
(thumb_find_work_register, arm_load_pic_register,
legitimize_tls_address, arm_address_cost, load_multiple_sequence,
emit_ldm_seq, emit_stm_seq, arm_select_cc_mode, get_jump_table_size,
print_multi_reg, output_mov_long_double_fpa_from_arm,
output_mov_long_double_arm_from_fpa, output_mov_double_fpa_from_arm,
output_mov_double_fpa_from_arm, output_move_double,
arm_compute_save_reg_mask, arm_compute_save_reg0_reg12_mask,
output_return_instruction, arm_output_function_prologue,
arm_output_epilogue, arm_get_frame_offsets, arm_regno_class,
arm_output_mi_thunk, thumb_set_return_address): Ditto.
(arm_expand_prologue): Handle Thumb-2. Use arm_save_coproc_regs.
(arm_coproc_mem_operand): Allow POST_INC/PRE_DEC.
(arithmetic_instr, shift_op): Use arm_shift_nmem.
(arm_print_operand): Use arm_print_condition. Handle '(', ')', '.',
'!' and 'L'.
(arm_final_prescan_insn): Use extract_constrain_insn_cached.
(thumb_expand_prologue): Use thumb_set_frame_pointer.
(arm_file_start): Output directive for unified syntax.
(arm_unwind_emit_set): Handle stack alignment instruction.
* config/arm/lib1funcs.asm: Remove default for __ARM_ARCH__.
Add v6t2, v7, v7a, v7r and v7m.
(RETLDM): Add Thumb-2 code.
(do_it, shift1, do_push, do_pop, COND, THUMB_SYNTAX): New macros.
* config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): Define __thumb2__.
(TARGET_THUMB1, TARGET_32BIT, TARGET_THUMB2, TARGET_DSP_MULTIPLY,
TARGET_INT_SIMD, TARGET_UNIFIED_ASM, ARM_FT_STACKALIGN, IS_STACKALIGN,
THUMB2_TRAMPOLINE_TEMPLATE, TRAMPOLINE_ADJUST_ADDRESS,
ASM_OUTPUT_OPCODE, THUMB2_GO_IF_LEGITIMATE_ADDRESS,
THUMB2_LEGITIMIZE_ADDRESS, CASE_VECTOR_PC_RELATIVE,
CASE_VECTOR_SHORTEN_MODE, ADDR_VEC_ALIGN, ASM_OUTPUT_CASE_END,
ADJUST_INSN_LENGTH): Define.
(TARGET_REALLY_IWMMXT, TARGET_IWMMXT_ABI, CONDITIONAL_REGISTER_USAGE,
STATIC_CHAIN_REGNUM, HARD_REGNO_NREGS, INDEX_REG_CLASS,
BASE_REG_CLASS, MODE_BASE_REG_CLASS, SMALL_REGISTER_CLASSES,
PREFERRED_RELOAD_CLASS, SECONDARY_OUTPUT_RELOAD_CLASS,
SECONDARY_INPUT_RELOAD_CLASS, LIBCALL_VALUE, FUNCTION_VALUE_REGNO_P,
TRAMPOLINE_SIZE, INITIALIZE_TRAMPOLINE, HAVE_PRE_INCREMENT,
HAVE_POST_DECREMENT, HAVE_PRE_DECREMENT, HAVE_PRE_MODIFY_DISP,
HAVE_POST_MODIFY_DISP, HAVE_PRE_MODIFY_REG, HAVE_POST_MODIFY_REG,
REGNO_MODE_OK_FOR_BASE_P, LEGITIMATE_CONSTANT_P,
REG_MODE_OK_FOR_BASE_P, REG_OK_FOR_INDEX_P, GO_IF_LEGITIMATE_ADDRESS,
LEGITIMIZE_ADDRESS, THUMB2_LEGITIMIZE_ADDRESS,
GO_IF_MODE_DEPENDENT_ADDRESS, MEMORY_MOVE_COST, BRANCH_COST,
ASM_APP_OFF, ASM_OUTPUT_CASE_LABEL, ARM_DECLARE_FUNCTION_NAME,
FINAL_PRESCAN_INSN, PRINT_OPERAND_PUNCT_VALID_P,
PRINT_OPERAND_ADDRESS): Adjust for Thumb-2.
(arm_arch_notm, arm_arch_thumb2, arm_arch_hwdiv): New declarations.
* config/arm/arm-cores.def: Add arm1156t2-s, cortex-a8, cortex-r4 and
cortex-m3.
* config/arm/arm-tune.md: Regenerate.
* config/arm/arm-protos.h: Update prototypes.
* config/arm/vfp.md: Enable patterns for Thumb-2.
(arm_movsi_vfp): Add movw alternative. Use output_move_vfp.
(arm_movdi_vfp, movsf_vfp, movdf_vfp): Use output_move_vfp.
(thumb2_movsi_vfp, thumb2_movdi_vfp, thumb2_movsf_vfp,
thumb2_movdf_vfp, thumb2_movsfcc_vfp, thumb2_movdfcc_vfp): New.
* config/arm/libunwind.S: Add Thumb-2 code.
* config/arm/constraints.md: Update include Thumb-2.
* config/arm/ieee754-sf.S: Add Thumb-2/Unified asm support.
* config/arm/ieee754-df.S: Ditto.
* config/arm/bpabi.S: Ditto.
* config/arm/t-arm (MD_INCLUDES): Add thumb2.md.
* config/arm/predicates.md (low_register_operand,
low_reg_or_int_operand, thumb_16bit_operator): New.
(thumb_cmp_operand, thumb_cmpneg_operand): Rename...
(thumb1_cmp_operand, thumb1_cmpneg_operand): ... to this.
* config/arm/t-arm-elf: Add armv7 multilib.
* config/arm/arm.md: Update patterns for Thumb-2 and Unified asm.
Include thumb2.md.
(UNSPEC_STACK_ALIGN, ce_count): New.
(arm_incscc, arm_decscc, arm_umaxsi3, arm_uminsi3,
arm_zero_extendsidi2, arm_zero_extendqidi2): New
insns/expanders.
* config/arm/fpa.md: Update patterns for Thumb-2 and Unified asm.
(thumb2_movsf_fpa, thumb2_movdf_fpa, thumb2_movxf_fpa,
thumb2_movsfcc_fpa, thumb2_movdfcc_fpa): New insns.
* config/arm/cirrus.md: Update patterns for Thumb-2 and Unified asm.
(cirrus_thumb2_movdi, cirrus_thumb2_movsi_insn,
thumb2_cirrus_movsf_hard_insn, thumb2_cirrus_movdf_hard_insn): New
insns.
* doc/extend.texi: Document ARMv7-M interrupt functions.
* doc/invoke.texi: Document Thumb-2 new cores+architectures.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@120408 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/arm/ieee754-sf.S')
-rw-r--r-- | gcc/config/arm/ieee754-sf.S | 166 |
1 files changed, 127 insertions, 39 deletions
diff --git a/gcc/config/arm/ieee754-sf.S b/gcc/config/arm/ieee754-sf.S index f74f458dd18..e36b4a4ed7e 100644 --- a/gcc/config/arm/ieee754-sf.S +++ b/gcc/config/arm/ieee754-sf.S @@ -1,6 +1,6 @@ /* ieee754-sf.S single-precision floating point support for ARM - Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation, Inc. Contributed by Nicolas Pitre (nico@cam.org) This file is free software; you can redistribute it and/or modify it @@ -71,36 +71,42 @@ ARM_FUNC_ALIAS aeabi_fadd addsf3 1: @ Look for zeroes, equal values, INF, or NAN. movs r2, r0, lsl #1 - movnes r3, r1, lsl #1 + do_it ne, ttt + COND(mov,s,ne) r3, r1, lsl #1 teqne r2, r3 - mvnnes ip, r2, asr #24 - mvnnes ip, r3, asr #24 + COND(mvn,s,ne) ip, r2, asr #24 + COND(mvn,s,ne) ip, r3, asr #24 beq LSYM(Lad_s) @ Compute exponent difference. Make largest exponent in r2, @ corresponding arg in r0, and positive exponent difference in r3. mov r2, r2, lsr #24 rsbs r3, r2, r3, lsr #24 + do_it gt, ttt addgt r2, r2, r3 eorgt r1, r0, r1 eorgt r0, r1, r0 eorgt r1, r0, r1 + do_it lt rsblt r3, r3, #0 @ If exponent difference is too large, return largest argument @ already in r0. We need up to 25 bit to handle proper rounding @ of 0x1p25 - 1.1. cmp r3, #25 + do_it hi RETc(hi) @ Convert mantissa to signed integer. tst r0, #0x80000000 orr r0, r0, #0x00800000 bic r0, r0, #0xff000000 + do_it ne rsbne r0, r0, #0 tst r1, #0x80000000 orr r1, r1, #0x00800000 bic r1, r1, #0xff000000 + do_it ne rsbne r1, r1, #0 @ If exponent == difference, one or both args were denormalized. @@ -114,15 +120,20 @@ LSYM(Lad_x): @ Shift and add second arg to first arg in r0. @ Keep leftover bits into r1. - adds r0, r0, r1, asr r3 + shiftop adds r0 r0 r1 asr r3 ip rsb r3, r3, #32 - mov r1, r1, lsl r3 + shift1 lsl, r1, r1, r3 @ Keep absolute value in r0-r1, sign in r3 (the n bit was set above) and r3, r0, #0x80000000 bpl LSYM(Lad_p) +#if defined(__thumb2__) + negs r1, r1 + sbc r0, r0, r0, lsl #1 +#else rsbs r1, r1, #0 rsc r0, r0, #0 +#endif @ Determine how to normalize the result. LSYM(Lad_p): @@ -147,6 +158,7 @@ LSYM(Lad_p): LSYM(Lad_e): cmp r1, #0x80000000 adc r0, r0, r2, lsl #23 + do_it eq biceq r0, r0, #1 orr r0, r0, r3 RET @@ -185,16 +197,23 @@ LSYM(Lad_l): clz ip, r0 sub ip, ip, #8 subs r2, r2, ip - mov r0, r0, lsl ip + shift1 lsl, r0, r0, ip #endif @ Final result with sign @ If exponent negative, denormalize result. + do_it ge, et addge r0, r0, r2, lsl #23 rsblt r2, r2, #0 orrge r0, r0, r3 +#if defined(__thumb2__) + do_it lt, t + lsrlt r0, r0, r2 + orrlt r0, r3, r0 +#else orrlt r0, r3, r0, lsr r2 +#endif RET @ Fixup and adjust bit position for denormalized arguments. @@ -202,6 +221,7 @@ LSYM(Lad_l): LSYM(Lad_d): teq r2, #0 eor r1, r1, #0x00800000 + do_it eq, te eoreq r0, r0, #0x00800000 addeq r2, r2, #1 subne r3, r3, #1 @@ -211,7 +231,8 @@ LSYM(Lad_s): mov r3, r1, lsl #1 mvns ip, r2, asr #24 - mvnnes ip, r3, asr #24 + do_it ne + COND(mvn,s,ne) ip, r3, asr #24 beq LSYM(Lad_i) teq r2, r3 @@ -219,12 +240,14 @@ LSYM(Lad_s): @ Result is x + 0.0 = x or 0.0 + y = y. teq r2, #0 + do_it eq moveq r0, r1 RET 1: teq r0, r1 @ Result is x - x = 0. + do_it ne, t movne r0, #0 RETc(ne) @@ -232,9 +255,11 @@ LSYM(Lad_s): tst r2, #0xff000000 bne 2f movs r0, r0, lsl #1 + do_it cs orrcs r0, r0, #0x80000000 RET 2: adds r2, r2, #(2 << 24) + do_it cc, t addcc r0, r0, #(1 << 23) RETc(cc) and r3, r0, #0x80000000 @@ -253,11 +278,13 @@ LSYM(Lad_o): @ otherwise return r0 (which is INF or -INF) LSYM(Lad_i): mvns r2, r2, asr #24 + do_it ne, et movne r0, r1 - mvneqs r3, r3, asr #24 + COND(mvn,s,eq) r3, r3, asr #24 movne r1, r0 movs r2, r0, lsl #9 - moveqs r3, r1, lsl #9 + do_it eq, te + COND(mov,s,eq) r3, r1, lsl #9 teqeq r0, r1 orrne r0, r0, #0x00400000 @ quiet NAN RET @@ -278,9 +305,11 @@ ARM_FUNC_START floatsisf ARM_FUNC_ALIAS aeabi_i2f floatsisf ands r3, r0, #0x80000000 + do_it mi rsbmi r0, r0, #0 1: movs ip, r0 + do_it eq RETc(eq) @ Add initial exponent to sign @@ -302,7 +331,10 @@ ARM_FUNC_ALIAS aeabi_ul2f floatundisf orrs r2, r0, r1 #if !defined (__VFP_FP__) && !defined(__SOFTFP__) + do_itt eq mvfeqs f0, #0.0 +#else + do_it eq #endif RETc(eq) @@ -314,14 +346,22 @@ ARM_FUNC_ALIAS aeabi_l2f floatdisf orrs r2, r0, r1 #if !defined (__VFP_FP__) && !defined(__SOFTFP__) + do_it eq, t mvfeqs f0, #0.0 +#else + do_it eq #endif RETc(eq) ands r3, ah, #0x80000000 @ sign bit in r3 bpl 1f +#if defined(__thumb2__) + negs al, al + sbc ah, ah, ah, lsl #1 +#else rsbs al, al, #0 rsc ah, ah, #0 +#endif 1: #if !defined (__VFP_FP__) && !defined(__SOFTFP__) @ For hard FPA code we want to return via the tail below so that @@ -332,12 +372,14 @@ ARM_FUNC_ALIAS aeabi_l2f floatdisf #endif movs ip, ah + do_it eq, tt moveq ip, al moveq ah, al moveq al, #0 @ Add initial exponent to sign orr r3, r3, #((127 + 23 + 32) << 23) + do_it eq subeq r3, r3, #(32 << 23) 2: sub r3, r3, #(1 << 23) @@ -345,15 +387,19 @@ ARM_FUNC_ALIAS aeabi_l2f floatdisf mov r2, #23 cmp ip, #(1 << 16) + do_it hs, t movhs ip, ip, lsr #16 subhs r2, r2, #16 cmp ip, #(1 << 8) + do_it hs, t movhs ip, ip, lsr #8 subhs r2, r2, #8 cmp ip, #(1 << 4) + do_it hs, t movhs ip, ip, lsr #4 subhs r2, r2, #4 cmp ip, #(1 << 2) + do_it hs, e subhs r2, r2, #2 sublo r2, r2, ip, lsr #1 subs r2, r2, ip, lsr #3 @@ -368,19 +414,21 @@ ARM_FUNC_ALIAS aeabi_l2f floatdisf sub r3, r3, r2, lsl #23 blt 3f - add r3, r3, ah, lsl r2 - mov ip, al, lsl r2 + shiftop add r3 r3 ah lsl r2 ip + shift1 lsl, ip, al, r2 rsb r2, r2, #32 cmp ip, #0x80000000 - adc r0, r3, al, lsr r2 + shiftop adc r0 r3 al lsr r2 r2 + do_it eq biceq r0, r0, #1 RET 3: add r2, r2, #32 - mov ip, ah, lsl r2 + shift1 lsl, ip, ah, r2 rsb r2, r2, #32 orrs al, al, ip, lsl #1 - adc r0, r3, ah, lsr r2 + shiftop adc r0 r3 ah lsr r2 r2 + do_it eq biceq r0, r0, ip, lsr #31 RET @@ -408,7 +456,8 @@ ARM_FUNC_ALIAS aeabi_fmul mulsf3 @ Mask out exponents, trap any zero/denormal/INF/NAN. mov ip, #0xff ands r2, ip, r0, lsr #23 - andnes r3, ip, r1, lsr #23 + do_it ne, tt + COND(and,s,ne) r3, ip, r1, lsr #23 teqne r2, ip teqne r3, ip beq LSYM(Lml_s) @@ -424,7 +473,8 @@ LSYM(Lml_x): @ If power of two, branch to a separate path. @ Make up for final alignment. movs r0, r0, lsl #9 - movnes r1, r1, lsl #9 + do_it ne + COND(mov,s,ne) r1, r1, lsl #9 beq LSYM(Lml_1) mov r3, #0x08000000 orr r0, r3, r0, lsr #5 @@ -436,7 +486,7 @@ LSYM(Lml_x): and r3, ip, #0x80000000 @ Well, no way to make it shorter without the umull instruction. - stmfd sp!, {r3, r4, r5} + do_push {r3, r4, r5} mov r4, r0, lsr #16 mov r5, r1, lsr #16 bic r0, r0, r4, lsl #16 @@ -447,7 +497,7 @@ LSYM(Lml_x): mla r0, r4, r1, r0 adds r3, r3, r0, lsl #16 adc r1, ip, r0, lsr #16 - ldmfd sp!, {r0, r4, r5} + do_pop {r0, r4, r5} #else @@ -461,6 +511,7 @@ LSYM(Lml_x): @ Adjust result upon the MSB position. cmp r1, #(1 << 23) + do_it cc, tt movcc r1, r1, lsl #1 orrcc r1, r1, r3, lsr #31 movcc r3, r3, lsl #1 @@ -476,6 +527,7 @@ LSYM(Lml_x): @ Round the result, merge final exponent. cmp r3, #0x80000000 adc r0, r0, r2, lsl #23 + do_it eq biceq r0, r0, #1 RET @@ -483,11 +535,13 @@ LSYM(Lml_x): LSYM(Lml_1): teq r0, #0 and ip, ip, #0x80000000 + do_it eq moveq r1, r1, lsl #9 orr r0, ip, r0, lsr #9 orr r0, r0, r1, lsr #9 subs r2, r2, #127 - rsbgts r3, r2, #255 + do_it gt, tt + COND(rsb,s,gt) r3, r2, #255 orrgt r0, r0, r2, lsl #23 RETc(gt) @@ -502,18 +556,20 @@ LSYM(Lml_u): @ Check if denormalized result is possible, otherwise return signed 0. cmn r2, #(24 + 1) + do_it le, t bicle r0, r0, #0x7fffffff RETc(le) @ Shift value right, round, etc. rsb r2, r2, #0 movs r1, r0, lsl #1 - mov r1, r1, lsr r2 + shift1 lsr, r1, r1, r2 rsb r2, r2, #32 - mov ip, r0, lsl r2 + shift1 lsl, ip, r0, r2 movs r0, r1, rrx adc r0, r0, #0 orrs r3, r3, ip, lsl #1 + do_it eq biceq r0, r0, ip, lsr #31 RET @@ -522,14 +578,16 @@ LSYM(Lml_u): LSYM(Lml_d): teq r2, #0 and ip, r0, #0x80000000 -1: moveq r0, r0, lsl #1 +1: do_it eq, tt + moveq r0, r0, lsl #1 tsteq r0, #0x00800000 subeq r2, r2, #1 beq 1b orr r0, r0, ip teq r3, #0 and ip, r1, #0x80000000 -2: moveq r1, r1, lsl #1 +2: do_it eq, tt + moveq r1, r1, lsl #1 tsteq r1, #0x00800000 subeq r3, r3, #1 beq 2b @@ -540,12 +598,14 @@ LSYM(Lml_s): @ Isolate the INF and NAN cases away and r3, ip, r1, lsr #23 teq r2, ip + do_it ne teqne r3, ip beq 1f @ Here, one or more arguments are either denormalized or zero. bics ip, r0, #0x80000000 - bicnes ip, r1, #0x80000000 + do_it ne + COND(bic,s,ne) ip, r1, #0x80000000 bne LSYM(Lml_d) @ Result is 0, but determine sign anyway. @@ -556,6 +616,7 @@ LSYM(Lml_z): 1: @ One or both args are INF or NAN. teq r0, #0x0 + do_it ne, ett teqne r0, #0x80000000 moveq r0, r1 teqne r1, #0x0 @@ -568,6 +629,7 @@ LSYM(Lml_z): 1: teq r3, ip bne LSYM(Lml_i) movs r3, r1, lsl #9 + do_it ne movne r0, r1 bne LSYM(Lml_n) @ <anything> * NAN -> NAN @@ -597,7 +659,8 @@ ARM_FUNC_ALIAS aeabi_fdiv divsf3 @ Mask out exponents, trap any zero/denormal/INF/NAN. mov ip, #0xff ands r2, ip, r0, lsr #23 - andnes r3, ip, r1, lsr #23 + do_it ne, tt + COND(and,s,ne) r3, ip, r1, lsr #23 teqne r2, ip teqne r3, ip beq LSYM(Ldv_s) @@ -624,25 +687,31 @@ LSYM(Ldv_x): @ Ensure result will land to known bit position. @ Apply exponent bias accordingly. cmp r3, r1 + do_it cc movcc r3, r3, lsl #1 adc r2, r2, #(127 - 2) @ The actual division loop. mov ip, #0x00800000 1: cmp r3, r1 + do_it cs, t subcs r3, r3, r1 orrcs r0, r0, ip cmp r3, r1, lsr #1 + do_it cs, t subcs r3, r3, r1, lsr #1 orrcs r0, r0, ip, lsr #1 cmp r3, r1, lsr #2 + do_it cs, t subcs r3, r3, r1, lsr #2 orrcs r0, r0, ip, lsr #2 cmp r3, r1, lsr #3 + do_it cs, t subcs r3, r3, r1, lsr #3 orrcs r0, r0, ip, lsr #3 movs r3, r3, lsl #4 - movnes ip, ip, lsr #4 + do_it ne + COND(mov,s,ne) ip, ip, lsr #4 bne 1b @ Check exponent for under/overflow. @@ -652,6 +721,7 @@ LSYM(Ldv_x): @ Round the result, merge final exponent. cmp r3, r1 adc r0, r0, r2, lsl #23 + do_it eq biceq r0, r0, #1 RET @@ -660,7 +730,8 @@ LSYM(Ldv_1): and ip, ip, #0x80000000 orr r0, ip, r0, lsr #9 adds r2, r2, #127 - rsbgts r3, r2, #255 + do_it gt, tt + COND(rsb,s,gt) r3, r2, #255 orrgt r0, r0, r2, lsl #23 RETc(gt) @@ -674,14 +745,16 @@ LSYM(Ldv_1): LSYM(Ldv_d): teq r2, #0 and ip, r0, #0x80000000 -1: moveq r0, r0, lsl #1 +1: do_it eq, tt + moveq r0, r0, lsl #1 tsteq r0, #0x00800000 subeq r2, r2, #1 beq 1b orr r0, r0, ip teq r3, #0 and ip, r1, #0x80000000 -2: moveq r1, r1, lsl #1 +2: do_it eq, tt + moveq r1, r1, lsl #1 tsteq r1, #0x00800000 subeq r3, r3, #1 beq 2b @@ -707,7 +780,8 @@ LSYM(Ldv_s): b LSYM(Lml_n) @ <anything> / NAN -> NAN 2: @ If both are nonzero, we need to normalize and resume above. bics ip, r0, #0x80000000 - bicnes ip, r1, #0x80000000 + do_it ne + COND(bic,s,ne) ip, r1, #0x80000000 bne LSYM(Ldv_d) @ One or both arguments are zero. bics r2, r0, #0x80000000 @@ -759,18 +833,24 @@ ARM_FUNC_ALIAS eqsf2 cmpsf2 mov r2, r0, lsl #1 mov r3, r1, lsl #1 mvns ip, r2, asr #24 - mvnnes ip, r3, asr #24 + do_it ne + COND(mvn,s,ne) ip, r3, asr #24 beq 3f @ Compare values. @ Note that 0.0 is equal to -0.0. 2: orrs ip, r2, r3, lsr #1 @ test if both are 0, clear C flag + do_it ne teqne r0, r1 @ if not 0 compare sign - subpls r0, r2, r3 @ if same sign compare values, set r0 + do_it pl + COND(sub,s,pl) r0, r2, r3 @ if same sign compare values, set r0 @ Result: + do_it hi movhi r0, r1, asr #31 + do_it lo mvnlo r0, r1, asr #31 + do_it ne orrne r0, r0, #1 RET @@ -806,14 +886,15 @@ ARM_FUNC_ALIAS aeabi_cfcmple aeabi_cfcmpeq @ The status-returning routines are required to preserve all @ registers except ip, lr, and cpsr. -6: stmfd sp!, {r0, r1, r2, r3, lr} +6: do_push {r0, r1, r2, r3, lr} ARM_CALL cmpsf2 @ Set the Z flag correctly, and the C flag unconditionally. - cmp r0, #0 + cmp r0, #0 @ Clear the C flag if the return value was -1, indicating @ that the first operand was smaller than the second. - cmnmi r0, #0 - RETLDM "r0, r1, r2, r3" + do_it mi + cmnmi r0, #0 + RETLDM "r0, r1, r2, r3" FUNC_END aeabi_cfcmple FUNC_END aeabi_cfcmpeq @@ -823,6 +904,7 @@ ARM_FUNC_START aeabi_fcmpeq str lr, [sp, #-8]! ARM_CALL aeabi_cfcmple + do_it eq, e moveq r0, #1 @ Equal to. movne r0, #0 @ Less than, greater than, or unordered. RETLDM @@ -833,6 +915,7 @@ ARM_FUNC_START aeabi_fcmplt str lr, [sp, #-8]! ARM_CALL aeabi_cfcmple + do_it cc, e movcc r0, #1 @ Less than. movcs r0, #0 @ Equal to, greater than, or unordered. RETLDM @@ -843,6 +926,7 @@ ARM_FUNC_START aeabi_fcmple str lr, [sp, #-8]! ARM_CALL aeabi_cfcmple + do_it ls, e movls r0, #1 @ Less than or equal to. movhi r0, #0 @ Greater than or unordered. RETLDM @@ -853,6 +937,7 @@ ARM_FUNC_START aeabi_fcmpge str lr, [sp, #-8]! ARM_CALL aeabi_cfrcmple + do_it ls, e movls r0, #1 @ Operand 2 is less than or equal to operand 1. movhi r0, #0 @ Operand 2 greater than operand 1, or unordered. RETLDM @@ -863,6 +948,7 @@ ARM_FUNC_START aeabi_fcmpgt str lr, [sp, #-8]! ARM_CALL aeabi_cfrcmple + do_it cc, e movcc r0, #1 @ Operand 2 is less than operand 1. movcs r0, #0 @ Operand 2 is greater than or equal to operand 1, @ or they are unordered. @@ -914,7 +1000,8 @@ ARM_FUNC_ALIAS aeabi_f2iz fixsfsi mov r3, r0, lsl #8 orr r3, r3, #0x80000000 tst r0, #0x80000000 @ the sign bit - mov r0, r3, lsr r2 + shift1 lsr, r0, r3, r2 + do_it ne rsbne r0, r0, #0 RET @@ -926,6 +1013,7 @@ ARM_FUNC_ALIAS aeabi_f2iz fixsfsi movs r2, r0, lsl #9 bne 4f @ r0 is NAN. 3: ands r0, r0, #0x80000000 @ the sign bit + do_it eq moveq r0, #0x7fffffff @ the maximum signed positive si RET @@ -954,7 +1042,7 @@ ARM_FUNC_ALIAS aeabi_f2uiz fixunssfsi @ scale the value mov r3, r0, lsl #8 orr r3, r3, #0x80000000 - mov r0, r3, lsr r2 + shift1 lsr, r0, r3, r2 RET 1: mov r0, #0 |