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.