Juha Montosen vastaus Demoihin 2.
;Muista: @ - global, % - local
declare double @llvm.sqrt.f64(double %value)
declare i32 @sprintf(i8*, i8*, ...)
declare i32 @scanf(i8*, ...)
declare i32 @puts(i8*)
declare i8* @malloc(i64)
@.just = private unnamed_addr constant [15 x i8] c"Just (%lf,%lf)\00"
@.noth = private unnamed_addr constant [8 x i8] c"Nothing\00"
@.scand = private unnamed_addr constant [4 x i8] c"%lf\00"
;Muodostellaan 2. asteen polynomiyhtälön ratkaisu, vain reaaliset juuret
;(r1,r2) = (-b \pm sqrt (b^2 - 4*a*c))/(2a)
define i8* @root(double %a, double %b, double %c) {
%default = alloca i8* ;Tämä on hieman "turha" vaihe, voisi hoitaa phillä tai 2x ret
store i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.noth, i64 0, i64 0), i8** %default
%b2 = fmul double %b, %b ;Lasketaan b^2
%ac = fmul double %a, %c ;Lasketaan a * c
%ss = fmul double 4.0, %ac ;Lasketaan 4 * ac
%i = fcmp oge double %b2, %ss ;Hypätään loppuun jos ei reaalisia ratkaisuja
br i1 %i, label %sol, label %soli
sol:
%ret_val = call i8* @malloc(i64 27) ;paluuarvolle tilaa (15-6+2*9=27)
%d = fsub double %b2, %ss ;diskriminantin lasku b^2-4ac
%a2 = fadd double %a, %a ;a + a = 2a
%bn = fsub double -0.0, %b ;-b
%t1 = fdiv double %bn, %a2 ;t1 = -b/2a voitaisiin jakaa vasta lopussa jolloin tarvitaan 1 fdiv
%ds = call double @llvm.sqrt.f64(double %d) ; sqrt d
%t2 = fdiv double %ds, %a2 ;jälkimmäinen termi (sqrt (b^2-4ac) / 2a)
%r1 = fadd double %t1, %t2 ;1. juuri
%r2 = fsub double %t1, %t2 ;2. juuri
%1 = call i32 (i8*, i8*, ...) @sprintf(i8* %ret_val, i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.just, i64 0, i64 0), double %r1, double %r2) ;sprintf ei ole paras mahdollinen tähän.
store i8* %ret_val, i8** %default
br label %soli
soli:
%2 = load i8*, i8** %default
ret i8* %2
}
define i32 @main() {
%val1 = alloca double
%val2 = alloca double
%val3 = alloca double
%1 = call i32 (i8*, ...) @scanf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.scand, i64 0, i64 0), double* %val1)
%2 = call i32 (i8*, ...) @scanf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.scand, i64 0, i64 0), double* %val2)
%3 = call i32 (i8*, ...) @scanf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.scand, i64 0, i64 0), double* %val3)
; luetaan muuttujien arvot muistista, koska haluamme kutsua arvoilla
%a = load double, double * %val1
%b = load double, double * %val2
%c = load double, double * %val3
%result = call i8* @root(double %a, double %b, double %c)
%4 = call i32 @puts(i8* %result)
ret i32 0
}
These are the current permissions for this document; please modify if needed. You can always modify these permissions from the manage page.