mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-26 05:32:25 +00:00
8e9ba0e588
int->fp conversions on PPC must be done through memory loads and stores. On a modern core, this process begins by storing the int value to memory, then loading it using a (sometimes special) FP load instruction. Unfortunately, we would do this even when the value to be converted was itself a load, and we can just use that same memory location instead of copying it to another first. There is a slight complication when handling int_to_fp(fp_to_int(x)) pairs, because the fp_to_int operand has not been lowered when the int_to_fp is being lowered. We handle this specially by invoking fp_to_int's lowering logic (partially) and getting the necessary memory location (some trivial refactoring was done to make this possible). This is all somewhat ugly, and it would be nice if some later CodeGen stage could just clean this stuff up, but because doing so would involve modifying target-specific nodes (or instructions), it is not immediately clear how that would work. Also, remove a related entry from the README.txt for which we now generate reasonable code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225301 91177308-0d34-0410-b5e6-96231b3b80d8
97 lines
2.3 KiB
LLVM
97 lines
2.3 KiB
LLVM
; RUN: llc -mcpu=a2 < %s | FileCheck %s
|
|
target datalayout = "E-m:e-i64:64-n32:64"
|
|
target triple = "powerpc64-unknown-linux-gnu"
|
|
|
|
; Function Attrs: nounwind readonly
|
|
define double @test1(i64* nocapture readonly %x) #0 {
|
|
entry:
|
|
%0 = load i64* %x, align 8
|
|
%conv = sitofp i64 %0 to double
|
|
ret double %conv
|
|
|
|
; CHECK-LABEL: @test1
|
|
; CHECK: lfd [[REG1:[0-9]+]], 0(3)
|
|
; CHECK: fcfid 1, [[REG1]]
|
|
; CHECK: blr
|
|
}
|
|
|
|
; Function Attrs: nounwind readonly
|
|
define double @test2(i32* nocapture readonly %x) #0 {
|
|
entry:
|
|
%0 = load i32* %x, align 4
|
|
%conv = sitofp i32 %0 to double
|
|
ret double %conv
|
|
|
|
; CHECK-LABEL: @test2
|
|
; CHECK: lfiwax [[REG1:[0-9]+]], 0, 3
|
|
; CHECK: fcfid 1, [[REG1]]
|
|
; CHECK: blr
|
|
}
|
|
|
|
; Function Attrs: nounwind readnone
|
|
define float @foo(float %X) #0 {
|
|
entry:
|
|
%conv = fptosi float %X to i32
|
|
%conv1 = sitofp i32 %conv to float
|
|
ret float %conv1
|
|
|
|
; CHECK-LABEL: @foo
|
|
; CHECK-DAG: fctiwz [[REG2:[0-9]+]], 1
|
|
; CHECK-DAG: addi [[REG1:[0-9]+]], 1,
|
|
; CHECK: stfiwx [[REG2]], 0, [[REG1]]
|
|
; CHECK: lfiwax [[REG3:[0-9]+]], 0, [[REG1]]
|
|
; CHECK: fcfids 1, [[REG3]]
|
|
; CHECK: blr
|
|
}
|
|
|
|
; Function Attrs: nounwind readnone
|
|
define double @food(double %X) #0 {
|
|
entry:
|
|
%conv = fptosi double %X to i32
|
|
%conv1 = sitofp i32 %conv to double
|
|
ret double %conv1
|
|
|
|
; CHECK-LABEL: @food
|
|
; CHECK-DAG: fctiwz [[REG2:[0-9]+]], 1
|
|
; CHECK-DAG: addi [[REG1:[0-9]+]], 1,
|
|
; CHECK: stfiwx [[REG2]], 0, [[REG1]]
|
|
; CHECK: lfiwax [[REG3:[0-9]+]], 0, [[REG1]]
|
|
; CHECK: fcfid 1, [[REG3]]
|
|
; CHECK: blr
|
|
}
|
|
|
|
; Function Attrs: nounwind readnone
|
|
define float @foou(float %X) #0 {
|
|
entry:
|
|
%conv = fptoui float %X to i32
|
|
%conv1 = uitofp i32 %conv to float
|
|
ret float %conv1
|
|
|
|
; CHECK-LABEL: @foou
|
|
; CHECK-DAG: fctiwuz [[REG2:[0-9]+]], 1
|
|
; CHECK-DAG: addi [[REG1:[0-9]+]], 1,
|
|
; CHECK: stfiwx [[REG2]], 0, [[REG1]]
|
|
; CHECK: lfiwzx [[REG3:[0-9]+]], 0, [[REG1]]
|
|
; CHECK: fcfidus 1, [[REG3]]
|
|
; CHECK: blr
|
|
}
|
|
|
|
; Function Attrs: nounwind readnone
|
|
define double @fooud(double %X) #0 {
|
|
entry:
|
|
%conv = fptoui double %X to i32
|
|
%conv1 = uitofp i32 %conv to double
|
|
ret double %conv1
|
|
|
|
; CHECK-LABEL: @fooud
|
|
; CHECK-DAG: fctiwuz [[REG2:[0-9]+]], 1
|
|
; CHECK-DAG: addi [[REG1:[0-9]+]], 1,
|
|
; CHECK: stfiwx [[REG2]], 0, [[REG1]]
|
|
; CHECK: lfiwzx [[REG3:[0-9]+]], 0, [[REG1]]
|
|
; CHECK: fcfidu 1, [[REG3]]
|
|
; CHECK: blr
|
|
}
|
|
|
|
attributes #0 = { nounwind readonly }
|
|
|