t-msp430 (LIB2ADD): Add lib2hw_mul.S
* config/msp430/t-msp430 (LIB2ADD): Add lib2hw_mul.S * config/msp430/lib2hw_mul.S: New: Hardware multiply routines. From-SVN: r208374
This commit is contained in:
parent
80662856d2
commit
df2b279c5c
@ -1,3 +1,8 @@
|
||||
2014-03-06 Nick Clifton <nickc@redhat.com>
|
||||
|
||||
* config/msp430/t-msp430 (LIB2ADD): Add lib2hw_mul.S
|
||||
* config/msp430/lib2hw_mul.S: New: Hardware multiply routines.
|
||||
|
||||
2014-02-28 Joey Ye <joey.ye@arm.com>
|
||||
|
||||
PR libgcc/60166
|
||||
|
226
libgcc/config/msp430/lib2hw_mul.S
Normal file
226
libgcc/config/msp430/lib2hw_mul.S
Normal file
@ -0,0 +1,226 @@
|
||||
; Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
; Contributed by Red Hat.
|
||||
;
|
||||
; This file is free software; you can redistribute it and/or modify it
|
||||
; under the terms of the GNU General Public License as published by the
|
||||
; Free Software Foundation; either version 3, or (at your option) any
|
||||
; later version.
|
||||
;
|
||||
; This file is distributed in the hope that it will be useful, but
|
||||
; WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
; General Public License for more details.
|
||||
;
|
||||
; Under Section 7 of GPL version 3, you are granted additional
|
||||
; permissions described in the GCC Runtime Library Exception, version
|
||||
; 3.1, as published by the Free Software Foundation.
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License and
|
||||
; a copy of the GCC Runtime Library Exception along with this program;
|
||||
; see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
||||
; <http://www.gnu.org/licenses/>.
|
||||
|
||||
.macro start_func name
|
||||
.pushsection .text.\name,"ax",@progbits
|
||||
.align 2
|
||||
.global \name
|
||||
.type \name , @function
|
||||
\name:
|
||||
PUSH.W sr ; Save current interrupt state
|
||||
DINT ; Disable interrupts
|
||||
NOP ; Account for latency
|
||||
.endm
|
||||
|
||||
.macro end_func name
|
||||
#ifdef __MSP430X_LARGE__
|
||||
POP.W sr
|
||||
RETA
|
||||
#else
|
||||
RETI
|
||||
#endif
|
||||
.size \name , . - \name
|
||||
.popsection
|
||||
.endm
|
||||
|
||||
.macro mult16 OP1, OP2, RESULT
|
||||
;* * 16-bit hardware multiply: int16 = int16 * int16
|
||||
;*
|
||||
;* - Operand 1 is in R12
|
||||
;* - Operand 2 is in R13
|
||||
;* - Result is in R12
|
||||
;*
|
||||
;* To ensure that the multiply is performed atomically, interrupts are
|
||||
;* disabled upon routine entry. Interrupt state is restored upon exit.
|
||||
;*
|
||||
;* Registers used: R12, R13
|
||||
;*
|
||||
;* Macro arguments are the memory locations of the hardware registers.
|
||||
|
||||
MOV.W r12, &\OP1 ; Load operand 1 into multiplier
|
||||
MOV.W r13, &\OP2 ; Load operand 2 which triggers MPY
|
||||
MOV.W &\RESULT, r12 ; Move result into return register
|
||||
.endm
|
||||
|
||||
.macro mult1632 OP1, OP2, RESULT_LO, RESULT_HI
|
||||
;* * 16-bit hardware multiply with a 32-bit result:
|
||||
;* int32 = int16 * int16
|
||||
;* uint32 = uint16 * uint16
|
||||
;*
|
||||
;* - Operand 1 is in R12
|
||||
;* - Operand 2 is in R13
|
||||
;* - Result is in R12, R13
|
||||
;*
|
||||
;* To ensure that the multiply is performed atomically, interrupts are
|
||||
;* disabled upon routine entry. Interrupt state is restored upon exit.
|
||||
;*
|
||||
;* Registers used: R12, R13
|
||||
;*
|
||||
;* Macro arguments are the memory locations of the hardware registers.
|
||||
|
||||
MOV.W r12, &\OP1 ; Load operand 1 into multiplier
|
||||
MOV.W r13, &\OP2 ; Load operand 2 which triggers MPY
|
||||
MOV.W &\RESULT_LO, r12 ; Move low result into return register
|
||||
MOV.W &\RESULT_HI, r13 ; Move high result into return register
|
||||
.endm
|
||||
|
||||
.macro mult32 OP1, OP2, MAC_OP1, MAC_OP2, RESULT_LO, RESULT_HI
|
||||
;* * 32-bit hardware multiply with a 32-bit result using 16 multiply and accumulate:
|
||||
;* int32 = int32 * int32
|
||||
;*
|
||||
;* - Operand 1 is in R12, R13
|
||||
;* - Operand 2 is in R14, R15
|
||||
;* - Result is in R12, R13
|
||||
;*
|
||||
;* To ensure that the multiply is performed atomically, interrupts are
|
||||
;* disabled upon routine entry. Interrupt state is restored upon exit.
|
||||
;*
|
||||
;* Registers used: R12, R13, R14, R15
|
||||
;*
|
||||
;* Macro arguments are the memory locations of the hardware registers.
|
||||
|
||||
MOV.W r12, &\OP1 ; Load operand 1 Low into multiplier
|
||||
MOV.W r14, &\OP2 ; Load operand 2 Low which triggers MPY
|
||||
MOV.W r12, &\MAC_OP1 ; Load operand 1 Low into mac
|
||||
MOV.W &\RESULT_LO, r12 ; Low 16-bits of result ready for return
|
||||
MOV.W &\RESULT_HI, &\RESULT_LO; MOV intermediate mpy high into low
|
||||
MOV.W r15, &\MAC_OP2 ; Load operand 2 High, trigger MAC
|
||||
MOV.W r13, &\MAC_OP1 ; Load operand 1 High
|
||||
MOV.W r14, &\MAC_OP2 ; Load operand 2 Lo, trigger MAC
|
||||
MOV.W &\RESULT_LO, r13 ; Upper 16-bits result ready for return
|
||||
.endm
|
||||
|
||||
|
||||
.macro mult32_hw OP1_LO OP1_HI OP2_LO OP2_HI RESULT_LO RESULT_HI
|
||||
;* * 32-bit hardware multiply with a 32-bit result
|
||||
;* int32 = int32 * int32
|
||||
;*
|
||||
;* - Operand 1 is in R12, R13
|
||||
;* - Operand 2 is in R14, R15
|
||||
;* - Result is in R12, R13
|
||||
;*
|
||||
;* To ensure that the multiply is performed atomically, interrupts are
|
||||
;* disabled upon routine entry. Interrupt state is restored upon exit.
|
||||
;*
|
||||
;* Registers used: R12, R13, R14, R15
|
||||
;*
|
||||
;* Macro arguments are the memory locations of the hardware registers.
|
||||
|
||||
MOV.W r12, &\OP1_LO ; Load operand 1 Low into multiplier
|
||||
MOV.W r13, &\OP1_HI ; Load operand 1 High into multiplier
|
||||
MOV.W r14, &\OP2_LO ; Load operand 2 Low into multiplier
|
||||
MOV.W r15, &\OP2_HI ; Load operand 2 High, trigger MPY
|
||||
MOV.W &\RESULT_LO, r12 ; Ready low 16-bits for return
|
||||
MOV.W &\RESULT_HI, r13 ; Ready high 16-bits for return
|
||||
.endm
|
||||
|
||||
.macro mult3264_hw OP1_LO OP1_HI OP2_LO OP2_HI RES0 RES1 RES2 RES3
|
||||
;* * 32-bit hardware multiply with a 64-bit result
|
||||
;* int64 = int32 * int32
|
||||
;* uint64 = uint32 * uint32
|
||||
;*
|
||||
;* - Operand 1 is in R12, R13
|
||||
;* - Operand 2 is in R14, R15
|
||||
;* - Result is in R12, R13, R14, R15
|
||||
;*
|
||||
;* To ensure that the multiply is performed atomically, interrupts are
|
||||
;* disabled upon routine entry. Interrupt state is restored upon exit.
|
||||
;*
|
||||
;* Registers used: R12, R13, R14, R15
|
||||
;*
|
||||
;* Macro arguments are the memory locations of the hardware registers.
|
||||
|
||||
MOV.W r12, &\OP1_LO ; Load operand 1 Low into multiplier
|
||||
MOV.W r13, &\OP1_HI ; Load operand 1 High into multiplier
|
||||
MOV.W r14, &\OP2_LO ; Load operand 2 Low into multiplier
|
||||
MOV.W r15, &\OP2_HI ; Load operand 2 High, trigger MPY
|
||||
MOV.W &\RES0, R12 ; Ready low 16-bits for return
|
||||
MOV.W &\RES1, R13 ;
|
||||
MOV.W &\RES2, R14 ;
|
||||
MOV.W &\RES3, R15 ; Ready high 16-bits for return
|
||||
.endm
|
||||
|
||||
|
||||
;; First generation MSP430 hardware multiplies ....
|
||||
|
||||
.set MPY_OP1, 0x0130
|
||||
.set MPY_OP1_S, 0x0132
|
||||
.set MAC_OP1, 0x0134
|
||||
.set MPY_OP2, 0x0138
|
||||
.set MAC_OP2, 0x0138
|
||||
.set RESULT_LO, 0x013A
|
||||
.set RESULT_HI, 0x013C
|
||||
|
||||
start_func __mulhi2
|
||||
mult16 MPY_OP1, MPY_OP2, RESULT_LO
|
||||
end_func __mulhi2
|
||||
|
||||
start_func __mulsihi2
|
||||
mult1632 MPY_OP1_S, MPY_OP2, RESULT_LO, RESULT_HI
|
||||
end_func __mulsihi2
|
||||
|
||||
start_func __umulsihi2
|
||||
mult1632 MPY_OP1, MPY_OP2, RESULT_LO, RESULT_HI
|
||||
end_func __umulsihi2
|
||||
|
||||
start_func __mulsi2
|
||||
mult32 MPY_OP1, MPY_OP2, MAC_OP1, MAC_OP2, RESULT_LO, RESULT_HI
|
||||
end_func __mulsi2
|
||||
|
||||
start_func __mulsi2_hw32
|
||||
mult32_hw 0x0140, 0x0142, 0x0150, 0x0152, 0x0154, 0x0156
|
||||
end_func __mulsi2_hw32
|
||||
|
||||
start_func __muldisi2_hw32
|
||||
mult3264_hw 0x0144, 0x146, 0x0150, 0x0152, 0x0154, 0x0156, 0x0158, 0x015A
|
||||
end_func __muldisi2_hw32
|
||||
|
||||
start_func __umuldisi2_hw32
|
||||
mult3264_hw 0x0140, 0x142, 0x0150, 0x0152, 0x0154, 0x0156, 0x0158, 0x015A
|
||||
end_func __umuldisi2_hw32
|
||||
|
||||
/* The F5xxx series of MCUs support the same 16-bit hardware
|
||||
multiply, but it is accessed from different memory registers. */
|
||||
|
||||
start_func __mulhi2_f5
|
||||
mult16 0x04C0, 0x04C8, 0x04CA
|
||||
end_func __mulhi2_f5
|
||||
|
||||
start_func __mulsihi2_f5
|
||||
mult1632 0x04C2, 0x04C8, 0x04CA, 0x04CC
|
||||
end_func __mulsihi2_f5
|
||||
|
||||
start_func __umulsihi2_f5
|
||||
mult1632 0x04C0, 0x04C8, 0x04CA, 0x04CC
|
||||
end_func __umulsihi2_f5
|
||||
|
||||
start_func __mulsi2_f5
|
||||
mult32_hw 0x04D0, 0x04D2, 0x04E0, 0x04E2, 0x04E4, 0x04E6
|
||||
end_func __mulsi2_f5
|
||||
|
||||
start_func __muldisi2_f5
|
||||
mult3264_hw 0x04D4, 0x04D6, 0x04E0, 0x04E2, 0x04E4, 0x04E6, 0x04E8, 0x04EA
|
||||
end_func __muldisi2_f5
|
||||
|
||||
start_func __umuldisi2_f5
|
||||
mult3264_hw 0x04D0, 0x04D2, 0x04E0, 0x04E2, 0x04E4, 0x04E6, 0x04E8, 0x04EA
|
||||
end_func __umuldisi2_f5
|
@ -35,6 +35,7 @@ LIB2ADD = \
|
||||
$(srcdir)/config/msp430/srai.S \
|
||||
$(srcdir)/config/msp430/srli.S \
|
||||
$(srcdir)/config/msp430/cmpsi2.S \
|
||||
$(srcdir)/config/msp430/lib2hw_mul.S \
|
||||
$(srcdir)/config/msp430/floatunhisf.c \
|
||||
$(srcdir)/config/msp430/floatunhidf.c \
|
||||
$(srcdir)/config/msp430/floathidf.c \
|
||||
|
Loading…
x
Reference in New Issue
Block a user