mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	The Cortex-M7 has 3 options for its FPU: none, FPv5-SP-D16 and FPv5-DP-D16. FPv5 has the same instructions as FP-ARMv8, so it can be modelled using the same target feature, and all double-precision operations are already disabled by the fp-only-sp target features. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218747 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			302 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			LLVM
		
	
	
	
	
	
			
		
		
	
	
			302 lines
		
	
	
		
			6.8 KiB
		
	
	
	
		
			LLVM
		
	
	
	
	
	
| ; RUN: llc < %s -mtriple=thumbv7-none-eabi   -mcpu=cortex-m3 | FileCheck %s -check-prefix=CHECK -check-prefix=NONE
 | |
| ; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mcpu=cortex-m4 | FileCheck %s -check-prefix=CHECK -check-prefix=HARD -check-prefix=SP
 | |
| ; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mcpu=cortex-m7 | FileCheck %s -check-prefix=CHECK -check-prefix=HARD -check-prefix=DP
 | |
| ; RUN: llc < %s -mtriple=thumbv7-none-eabihf -mcpu=cortex-a8 | FileCheck %s -check-prefix=CHECK -check-prefix=HARD -check-prefix=DP
 | |
| 
 | |
| 
 | |
| 
 | |
| define i1 @cmp_f_false(float %a, float %b) {
 | |
| ; CHECK-LABEL: cmp_f_false:
 | |
| ; NONE: movs r0, #0
 | |
| ; HARD: movs r0, #0
 | |
|   %1 = fcmp false float %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| define i1 @cmp_f_oeq(float %a, float %b) {
 | |
| ; CHECK-LABEL: cmp_f_oeq:
 | |
| ; NONE: bl __aeabi_fcmpeq
 | |
| ; HARD: vcmpe.f32
 | |
| ; HARD: moveq r0, #1
 | |
|   %1 = fcmp oeq float %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| define i1 @cmp_f_ogt(float %a, float %b) {
 | |
| ; CHECK-LABEL: cmp_f_ogt:
 | |
| ; NONE: bl __aeabi_fcmpgt
 | |
| ; HARD: vcmpe.f32
 | |
| ; HARD: movgt r0, #1
 | |
|   %1 = fcmp ogt float %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| define i1 @cmp_f_oge(float %a, float %b) {
 | |
| ; CHECK-LABEL: cmp_f_oge:
 | |
| ; NONE: bl __aeabi_fcmpge
 | |
| ; HARD: vcmpe.f32
 | |
| ; HARD: movge r0, #1
 | |
|   %1 = fcmp oge float %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| define i1 @cmp_f_olt(float %a, float %b) {
 | |
| ; CHECK-LABEL: cmp_f_olt:
 | |
| ; NONE: bl __aeabi_fcmplt
 | |
| ; HARD: vcmpe.f32
 | |
| ; HARD: movmi r0, #1
 | |
|   %1 = fcmp olt float %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| define i1 @cmp_f_ole(float %a, float %b) {
 | |
| ; CHECK-LABEL: cmp_f_ole:
 | |
| ; NONE: bl __aeabi_fcmple
 | |
| ; HARD: vcmpe.f32
 | |
| ; HARD: movls r0, #1
 | |
|   %1 = fcmp ole float %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| define i1 @cmp_f_one(float %a, float %b) {
 | |
| ; CHECK-LABEL: cmp_f_one:
 | |
| ; NONE: bl __aeabi_fcmpgt
 | |
| ; NONE: bl __aeabi_fcmplt
 | |
| ; HARD: vcmpe.f32
 | |
| ; HARD: movmi r0, #1
 | |
| ; HARD: movgt r0, #1
 | |
|   %1 = fcmp one float %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| define i1 @cmp_f_ord(float %a, float %b) {
 | |
| ; CHECK-LABEL: cmp_f_ord:
 | |
| ; NONE: bl __aeabi_fcmpun
 | |
| ; HARD: vcmpe.f32
 | |
| ; HARD: movvc r0, #1
 | |
|   %1 = fcmp ord float %a, %b
 | |
|   ret i1 %1
 | |
| }define i1 @cmp_f_ueq(float %a, float %b) {
 | |
| ; CHECK-LABEL: cmp_f_ueq:
 | |
| ; NONE: bl __aeabi_fcmpeq
 | |
| ; NONE: bl __aeabi_fcmpun
 | |
| ; HARD: vcmpe.f32
 | |
| ; HARD: moveq r0, #1
 | |
| ; HARD: movvs r0, #1
 | |
|   %1 = fcmp ueq float %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| define i1 @cmp_f_ugt(float %a, float %b) {
 | |
| ; CHECK-LABEL: cmp_f_ugt:
 | |
| ; NONE: bl __aeabi_fcmpgt
 | |
| ; NONE: bl __aeabi_fcmpun
 | |
| ; HARD: vcmpe.f32
 | |
| ; HARD: movhi r0, #1
 | |
|   %1 = fcmp ugt float %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| define i1 @cmp_f_uge(float %a, float %b) {
 | |
| ; CHECK-LABEL: cmp_f_uge:
 | |
| ; NONE: bl __aeabi_fcmpge
 | |
| ; NONE: bl __aeabi_fcmpun
 | |
| ; HARD: vcmpe.f32
 | |
| ; HARD: movpl r0, #1
 | |
|   %1 = fcmp uge float %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| define i1 @cmp_f_ult(float %a, float %b) {
 | |
| ; CHECK-LABEL: cmp_f_ult:
 | |
| ; NONE: bl __aeabi_fcmplt
 | |
| ; NONE: bl __aeabi_fcmpun
 | |
| ; HARD: vcmpe.f32
 | |
| ; HARD: movlt r0, #1
 | |
|   %1 = fcmp ult float %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| define i1 @cmp_f_ule(float %a, float %b) {
 | |
| ; CHECK-LABEL: cmp_f_ule:
 | |
| ; NONE: bl __aeabi_fcmple
 | |
| ; NONE: bl __aeabi_fcmpun
 | |
| ; HARD: vcmpe.f32
 | |
| ; HARD: movle r0, #1
 | |
|   %1 = fcmp ule float %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| define i1 @cmp_f_une(float %a, float %b) {
 | |
| ; CHECK-LABEL: cmp_f_une:
 | |
| ; NONE: bl __aeabi_fcmpeq
 | |
| ; HARD: vcmpe.f32
 | |
| ; HARD: movne r0, #1
 | |
|   %1 = fcmp une float %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| define i1 @cmp_f_uno(float %a, float %b) {
 | |
| ; CHECK-LABEL: cmp_f_uno:
 | |
| ; NONE: bl __aeabi_fcmpun
 | |
| ; HARD: vcmpe.f32
 | |
| ; HARD: movvs r0, #1
 | |
|   %1 = fcmp uno float %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| define i1 @cmp_f_true(float %a, float %b) {
 | |
| ; CHECK-LABEL: cmp_f_true:
 | |
| ; NONE: movs r0, #1
 | |
| ; HARD: movs r0, #1
 | |
|   %1 = fcmp true float %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| 
 | |
| define i1 @cmp_d_false(double %a, double %b) {
 | |
| ; CHECK-LABEL: cmp_d_false:
 | |
| ; NONE: movs r0, #0
 | |
| ; HARD: movs r0, #0
 | |
|   %1 = fcmp false double %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| define i1 @cmp_d_oeq(double %a, double %b) {
 | |
| ; CHECK-LABEL: cmp_d_oeq:
 | |
| ; NONE: bl __aeabi_dcmpeq
 | |
| ; SP: bl __aeabi_dcmpeq
 | |
| ; DP: vcmpe.f64
 | |
| ; DP: moveq r0, #1
 | |
|   %1 = fcmp oeq double %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| define i1 @cmp_d_ogt(double %a, double %b) {
 | |
| ; CHECK-LABEL: cmp_d_ogt:
 | |
| ; NONE: bl __aeabi_dcmpgt
 | |
| ; SP: bl __aeabi_dcmpgt
 | |
| ; DP: vcmpe.f64
 | |
| ; DP: movgt r0, #1
 | |
|   %1 = fcmp ogt double %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| define i1 @cmp_d_oge(double %a, double %b) {
 | |
| ; CHECK-LABEL: cmp_d_oge:
 | |
| ; NONE: bl __aeabi_dcmpge
 | |
| ; SP: bl __aeabi_dcmpge
 | |
| ; DP: vcmpe.f64
 | |
| ; DP: movge r0, #1
 | |
|   %1 = fcmp oge double %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| define i1 @cmp_d_olt(double %a, double %b) {
 | |
| ; CHECK-LABEL: cmp_d_olt:
 | |
| ; NONE: bl __aeabi_dcmplt
 | |
| ; SP: bl __aeabi_dcmplt
 | |
| ; DP: vcmpe.f64
 | |
| ; DP: movmi r0, #1
 | |
|   %1 = fcmp olt double %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| define i1 @cmp_d_ole(double %a, double %b) {
 | |
| ; CHECK-LABEL: cmp_d_ole:
 | |
| ; NONE: bl __aeabi_dcmple
 | |
| ; SP: bl __aeabi_dcmple
 | |
| ; DP: vcmpe.f64
 | |
| ; DP: movls r0, #1
 | |
|   %1 = fcmp ole double %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| define i1 @cmp_d_one(double %a, double %b) {
 | |
| ; CHECK-LABEL: cmp_d_one:
 | |
| ; NONE: bl __aeabi_dcmpgt
 | |
| ; NONE: bl __aeabi_dcmplt
 | |
| ; SP: bl __aeabi_dcmpgt
 | |
| ; SP: bl __aeabi_dcmplt
 | |
| ; DP: vcmpe.f64
 | |
| ; DP: movmi r0, #1
 | |
| ; DP: movgt r0, #1
 | |
|   %1 = fcmp one double %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| define i1 @cmp_d_ord(double %a, double %b) {
 | |
| ; CHECK-LABEL: cmp_d_ord:
 | |
| ; NONE: bl __aeabi_dcmpun
 | |
| ; SP: bl __aeabi_dcmpun
 | |
| ; DP: vcmpe.f64
 | |
| ; DP: movvc r0, #1
 | |
|   %1 = fcmp ord double %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| define i1 @cmp_d_ugt(double %a, double %b) {
 | |
| ; CHECK-LABEL: cmp_d_ugt:
 | |
| ; NONE: bl __aeabi_dcmpgt
 | |
| ; NONE: bl __aeabi_dcmpun
 | |
| ; SP: bl __aeabi_dcmpgt
 | |
| ; SP: bl __aeabi_dcmpun
 | |
| ; DP: vcmpe.f64
 | |
| ; DP: movhi r0, #1
 | |
|   %1 = fcmp ugt double %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| 
 | |
| define i1 @cmp_d_ult(double %a, double %b) {
 | |
| ; CHECK-LABEL: cmp_d_ult:
 | |
| ; NONE: bl __aeabi_dcmplt
 | |
| ; NONE: bl __aeabi_dcmpun
 | |
| ; SP: bl __aeabi_dcmplt
 | |
| ; SP: bl __aeabi_dcmpun
 | |
| ; DP: vcmpe.f64
 | |
| ; DP: movlt r0, #1
 | |
|   %1 = fcmp ult double %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| 
 | |
| 
 | |
| define i1 @cmp_d_uno(double %a, double %b) {
 | |
| ; CHECK-LABEL: cmp_d_uno:
 | |
| ; NONE: bl __aeabi_dcmpun
 | |
| ; SP: bl __aeabi_dcmpun
 | |
| ; DP: vcmpe.f64
 | |
| ; DP: movvs r0, #1
 | |
|   %1 = fcmp uno double %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| define i1 @cmp_d_true(double %a, double %b) {
 | |
| ; CHECK-LABEL: cmp_d_true:
 | |
| ; NONE: movs r0, #1
 | |
| ; HARD: movs r0, #1
 | |
|   %1 = fcmp true double %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| define i1 @cmp_d_ueq(double %a, double %b) {
 | |
| ; CHECK-LABEL: cmp_d_ueq:
 | |
| ; NONE: bl __aeabi_dcmpeq
 | |
| ; NONE: bl __aeabi_dcmpun
 | |
| ; SP: bl __aeabi_dcmpeq
 | |
| ; SP: bl __aeabi_dcmpun
 | |
| ; DP: vcmpe.f64
 | |
| ; DP: moveq r0, #1
 | |
| ; DP: movvs r0, #1
 | |
|   %1 = fcmp ueq double %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| 
 | |
| define i1 @cmp_d_uge(double %a, double %b) {
 | |
| ; CHECK-LABEL: cmp_d_uge:
 | |
| ; NONE: bl __aeabi_dcmpge
 | |
| ; NONE: bl __aeabi_dcmpun
 | |
| ; SP: bl __aeabi_dcmpge
 | |
| ; SP: bl __aeabi_dcmpun
 | |
| ; DP: vcmpe.f64
 | |
| ; DP: movpl r0, #1
 | |
|   %1 = fcmp uge double %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| 
 | |
| define i1 @cmp_d_ule(double %a, double %b) {
 | |
| ; CHECK-LABEL: cmp_d_ule:
 | |
| ; NONE: bl __aeabi_dcmple
 | |
| ; NONE: bl __aeabi_dcmpun
 | |
| ; SP: bl __aeabi_dcmple
 | |
| ; SP: bl __aeabi_dcmpun
 | |
| ; DP: vcmpe.f64
 | |
| ; DP: movle r0, #1
 | |
|   %1 = fcmp ule double %a, %b
 | |
|   ret i1 %1
 | |
| }
 | |
| 
 | |
| define i1 @cmp_d_une(double %a, double %b) {
 | |
| ; CHECK-LABEL: cmp_d_une:
 | |
| ; NONE: bl __aeabi_dcmpeq
 | |
| ; SP: bl __aeabi_dcmpeq
 | |
| ; DP: vcmpe.f64
 | |
| ; DP: movne r0, #1
 | |
|   %1 = fcmp une double %a, %b
 | |
|   ret i1 %1
 | |
| }
 |