1# Copyright (c) 2021-2022 Huawei Device Co., Ltd. 2# Licensed under the Apache License, Version 2.0 (the "License"); 3# you may not use this file except in compliance with the License. 4# You may obtain a copy of the License at 5# 6# http://www.apache.org/licenses/LICENSE-2.0 7# 8# Unless required by applicable law or agreed to in writing, software 9# distributed under the License is distributed on an "AS IS" BASIS, 10# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11# See the License for the specific language governing permissions and 12# limitations under the License. 13 14.record Math <external> 15.record IO <external> 16.record Globals{ 17 f64 SOLAR_MASS <static> 18 f64 DAYS_PER_YEAR <static> 19} 20 21.record Body{ 22 f64 x 23 f64 y 24 f64 z 25 f64 vx 26 f64 vy 27 f64 vz 28 f64 mass 29} 30 31.function f64 Math.sqrt(f64 a0) <external> 32.function f64 Math.absF64(f64 a0) <external> 33.function u1 main(){ 34 fldai.64 365.24 35 ststatic Globals.DAYS_PER_YEAR 36 fmovi.64 v3, 3.141592653589793 37 fldai.64 4.0 38 fmul2.64 v3 39 fmul2.64 v3 40 ststatic Globals.SOLAR_MASS 41 movi v0, 3 42 movi v1, 15000 43 fmovi.64 v2, -4.395717154909567 44 call test, v0, v1, v2 45 return 46} 47 48.function u1 test(i32 a0, i32 a1, f64 a2){ 49 fmovi.64 v0, 0.0 #ret 50 fmovi.64 v6, 0.01 51 movi v2, 5 52 mov v1, a0 #loop_counter 53 lda v1 54loop: 55 jgt a1, loop_exit 56 newarr v4, v2, Body[] 57 movi v3, 0 58 call.short Sun 59 starr.obj v4, v3 60 inci v3, 1 61 call.short Jupiter 62 starr.obj v4, v3 63 inci v3, 1 64 call.short Saturn 65 starr.obj v4, v3 66 inci v3, 1 67 call.short Uranus 68 starr.obj v4, v3 69 inci v3, 1 70 call.short Neptune 71 starr.obj v4, v3 72 call.short NBodySystem, v4 73 lda v1 74 muli 100 75 sta v3 #max 76 call.short energy, v4 77 fadd2.64 v0 78 sta.64 v0 79 movi v5, 0 80loop2: 81 lda v5 82 jeq v3, loop2_exit 83 call.short advance, v4, v6 84 inci v5, 1 85 jmp loop2 86loop2_exit: 87 call.short energy, v4 88 fadd2.64 v0 89 sta.64 v0 90 lda v1 91 muli 2 92 sta v1 93 jmp loop 94loop_exit: 95 lda.64 v0 96 fsub2.64 a2 97 sta.64 v0 98 call.short Math.absF64, v0 99 fldai.64 1e-13 100 fcmpl.64 v0 101 jltz exit_failure 102 ldai 0 103 return 104exit_failure: 105 ldai 1 106 return 107} 108 109.function void BodyInit(Body a0, f64 a1, f64 a2, f64 a3, f64 a4, f64 a5, f64 a6, f64 a7){ 110 lda.64 a1 111 stobj a0, Body.x 112 lda.64 a2 113 stobj a0, Body.y 114 lda.64 a3 115 stobj a0, Body.z 116 lda.64 a4 117 stobj a0, Body.vx 118 lda.64 a5 119 stobj a0, Body.vy 120 lda.64 a6 121 stobj a0, Body.vz 122 lda.64 a7 123 stobj a0, Body.mass 124 return.void 125} 126 127.function Body Jupiter(){ 128 ldstatic Globals.DAYS_PER_YEAR 129 sta.64 v8 130 ldstatic Globals.SOLAR_MASS 131 sta.64 v9 132 newobj v0, Body 133 fmovi.64 v1, 4.84143144246472090e+00 134 fmovi.64 v2, -1.16032004402742839e+00 135 fmovi.64 v3, -1.03622044471123109e-01 136 fldai.64 1.66007664274403694e-03 137 fmul2.64 v8 138 sta.64 v4 139 fldai.64 7.69901118419740425e-03 140 fmul2.64 v8 141 sta.64 v5 142 fldai.64 -6.90460016972063023e-05 143 fmul2.64 v8 144 sta.64 v6 145 fldai.64 9.54791938424326609e-04 146 fmul2.64 v9 147 sta.64 v7 148 call.range BodyInit, v0 149 lda.obj v0 150 return.obj 151} 152 153.function Body Saturn(){ 154 ldstatic Globals.DAYS_PER_YEAR 155 sta.64 v8 156 ldstatic Globals.SOLAR_MASS 157 sta.64 v9 158 newobj v0, Body 159 fmovi.64 v1, 8.34336671824457987e+00 160 fmovi.64 v2, 4.12479856412430479e+00 161 fmovi.64 v3, -4.03523417114321381e-01 162 fldai.64 -2.76742510726862411e-03 163 fmul2.64 v8 164 sta.64 v4 165 fldai.64 4.99852801234917238e-03 166 fmul2.64 v8 167 sta.64 v5 168 fldai.64 2.30417297573763929e-05 169 fmul2.64 v8 170 sta.64 v6 171 fldai.64 2.85885980666130812e-04 172 fmul2.64 v9 173 sta.64 v7 174 call.range BodyInit, v0 175 lda.obj v0 176 return.obj 177} 178 179.function Body Uranus(){ 180 ldstatic Globals.DAYS_PER_YEAR 181 sta.64 v8 182 ldstatic Globals.SOLAR_MASS 183 sta.64 v9 184 newobj v0, Body 185 fmovi.64 v1, 1.28943695621391310e+01 186 fmovi.64 v2, -1.51111514016986312e+01 187 fmovi.64 v3, -2.23307578892655734e-01 188 fldai.64 2.96460137564761618e-03 189 fmul2.64 v8 190 sta.64 v4 191 fldai.64 2.37847173959480950e-03 192 fmul2.64 v8 193 sta.64 v5 194 fldai.64 -2.96589568540237556e-05 195 fmul2.64 v8 196 sta.64 v6 197 fldai.64 4.36624404335156298e-05 198 fmul2.64 v9 199 sta.64 v7 200 call.range BodyInit, v0 201 lda.obj v0 202 return.obj 203} 204 205.function Body Neptune(){ 206 ldstatic Globals.DAYS_PER_YEAR 207 sta.64 v8 208 ldstatic Globals.SOLAR_MASS 209 sta.64 v9 210 newobj v0, Body 211 fmovi.64 v1, 1.53796971148509165e+01 212 fmovi.64 v2, -2.59193146099879641e+01 213 fmovi.64 v3, 1.79258772950371181e-01 214 fldai.64 2.68067772490389322e-03 215 fmul2.64 v8 216 sta.64 v4 217 fldai.64 1.62824170038242295e-03 218 fmul2.64 v8 219 sta.64 v5 220 fldai.64 -9.51592254519715870e-05 221 fmul2.64 v8 222 sta.64 v6 223 fldai.64 5.15138902046611451e-05 224 fmul2.64 v9 225 sta.64 v7 226 call.range BodyInit, v0 227 lda.obj v0 228 return.obj 229} 230 231.function Body Sun(){ 232 ldstatic Globals.SOLAR_MASS 233 sta.64 v7 234 newobj v0, Body 235 fmovi.64 v1, 0.0 236 fmovi.64 v2, 0.0 237 fmovi.64 v3, 0.0 238 fmovi.64 v4, 0.0 239 fmovi.64 v5, 0.0 240 fmovi.64 v6, 0.0 241 call.range BodyInit, v0 242 lda.obj v0 243 return.obj 244} 245 246.function Body offsetMomentum(Body a0, f64 a1, f64 a2, f64 a3){ 247 ldstatic Globals.SOLAR_MASS 248 sta.64 v0 249 lda.64 a1 250 fneg.64 251 fdiv2.64 v0 252 stobj a0, Body.vx 253 lda.64 a2 254 fneg.64 255 fdiv2.64 v0 256 stobj a0, Body.vy 257 lda.64 a3 258 fneg.64 259 fdiv2.64 v0 260 stobj a0, Body.vz 261 lda.obj a0 262 return.obj 263} 264 265.function void NBodySystem(Body[] a0){ 266 fmovi.64 v0, 0.0 #px 267 fmovi.64 v1, 0.0 #py 268 fmovi.64 v2, 0.0 #pz 269 lenarr a0 270 sta v3 #size 271 movi v4, 0 #loop_counter 272loop: 273 lda v4 274 jeq v3, loop_exit 275 ldarr.obj a0 276 sta.obj v5 277 ldobj v5, Body.mass 278 sta.64 v6 #m 279 ldobj v5, Body.vx 280 fmul2.64 v6 281 fadd2.64 v0 282 sta.64 v0 283 ldobj v5, Body.vy 284 fmul2.64 v6 285 fadd2.64 v1 286 sta.64 v1 287 ldobj v5, Body.vz 288 fmul2.64 v6 289 fadd2.64 v2 290 sta.64 v2 291 inci v4, 1 292 jmp loop 293loop_exit: 294 ldai 0 295 ldarr.obj a0 296 sta.obj v5 297 call offsetMomentum, v5, v0, v1, v2 298 return.void 299} 300 301.function void advance(Body[] a0, f64 a1){ 302 lenarr a0 303 sta v0 #size 304 movi v1, 0 #loop counter 305loop: 306 lda v1 307 jeq v0, loop_exit 308 ldarr.obj a0 309 sta.obj v2 #bodyi 310 lda v1 311 addi 1 312 sta v3 313loop2: 314 lda v3 315 jeq v0, loop2_exit 316 ldarr.obj a0 317 sta.obj v4 #bodyj 318 ldobj v4, Body.x 319 sta.64 v5 320 ldobj v2, Body.x 321 fsub2.64 v5 322 sta.64 v6 #dx 323 ldobj v4, Body.y 324 sta.64 v5 325 ldobj v2, Body.y 326 fsub2.64 v5 327 sta.64 v7 #dy 328 ldobj v4, Body.z 329 sta.64 v5 330 ldobj v2, Body.z 331 fsub2.64 v5 332 sta.64 v8 #dz 333 fmul2.64 v8 334 sta.64 v9 335 lda.64 v6 336 fmul2.64 v6 337 sta.64 v10 338 lda.64 v7 339 fmul2.64 v7 340 fadd2.64 v9 341 fadd2.64 v10 342 sta.64 v9 343 call.short Math.sqrt, v9 344 sta.64 v9 #distance 345 fmul2.64 v9 346 fmul2.64 v9 347 sta.64 v10 348 lda.64 a1 349 fdiv2.64 v10 350 sta.64 v10 #mag 351 ldobj v4, Body.mass 352 fmul2.64 v10 353 sta.64 v11 354 fmul2.64 v6 355 sta.64 v12 356 ldobj v2, Body.vx 357 fsub2.64 v12 358 stobj v2, Body.vx 359 lda.64 v11 360 fmul2.64 v7 361 sta.64 v12 362 ldobj v2, Body.vy 363 fsub2.64 v12 364 stobj v2, Body.vy 365 lda.64 v11 366 fmul2.64 v8 367 sta.64 v12 368 ldobj v2, Body.vz 369 fsub2.64 v12 370 stobj v2, Body.vz 371 ldobj v2, Body.mass 372 fmul2.64 v10 373 sta.64 v11 374 fmul2.64 v6 375 sta.64 v12 376 ldobj v4, Body.vx 377 fadd2.64 v12 378 stobj v4, Body.vx 379 lda.64 v11 380 fmul2.64 v7 381 sta.64 v12 382 ldobj v4, Body.vy 383 fadd2.64 v12 384 stobj v4, Body.vy 385 lda.64 v11 386 fmul2.64 v8 387 sta.64 v12 388 ldobj v4, Body.vz 389 fadd2.64 v12 390 stobj v4, Body.vz 391 inci v3, 1 392 jmp loop2 393loop2_exit: 394 inci v1, 1 395 jmp loop 396loop_exit: 397 movi v1, 0 398loop3: 399 lda v1 400 jeq v0, loop3_exit 401 ldarr.obj a0 402 sta.obj v2 #body 403 ldobj v2, Body.vx 404 fmul2.64 a1 405 sta.64 v12 406 ldobj v2, Body.x 407 fadd2.64 v12 408 stobj v2, Body.x 409 ldobj v2, Body.vy 410 fmul2.64 a1 411 sta.64 v12 412 ldobj v2, Body.y 413 fadd2.64 v12 414 stobj v2, Body.y 415 ldobj v2, Body.vz 416 fmul2.64 a1 417 sta.64 v12 418 ldobj v2, Body.z 419 fadd2.64 v12 420 stobj v2, Body.z 421 inci v1, 1 422 jmp loop3 423loop3_exit: 424 return.void 425} 426 427.function f64 energy(Body[] a0){ 428 lenarr a0 429 sta v0 #size 430 fmovi.64 v1, 0.0 #e 431 movi v2, 0 432loop: 433 lda v2 434 jeq v0, loop_exit 435 ldarr.obj a0 436 sta.obj v3 #bodyi 437 ldobj v3, Body.vx 438 sta.64 v4 439 fmul2.64 v4 440 sta.64 v4 441 ldobj v3, Body.vy 442 sta.64 v5 443 fmul2.64 v5 444 sta.64 v5 445 ldobj v3, Body.vz 446 sta.64 v6 447 fmul2.64 v6 448 fadd2.64 v5 449 fadd2.64 v4 450 sta.64 v4 451 fmovi.64 v5, 0.5 452 ldobj v3, Body.mass 453 fmul2.64 v4 454 fmul2.64 v5 455 fadd2.64 v1 456 sta.64 v1 457 lda v2 458 addi 1 459 sta v7 460loop2: 461 lda v7 462 jeq v0, loop2_exit 463 ldarr.obj a0 464 sta.obj v8 #bodyj 465 ldobj v8, Body.x 466 sta.64 v4 467 ldobj v3, Body.x 468 fsub2.64 v4 469 sta.64 v5 #dx 470 fmul2.64 v5 471 sta.64 v5 472 ldobj v8, Body.y 473 sta.64 v4 474 ldobj v3, Body.y 475 fsub2.64 v4 476 sta.64 v6 #dy 477 fmul2.64 v6 478 sta.64 v6 479 ldobj v8, Body.z 480 sta.64 v4 481 ldobj v3, Body.z 482 fsub2.64 v4 483 sta.64 v10 #dz 484 fmul2.64 v10 485 fadd2.64 v6 486 fadd2.64 v5 487 sta.64 v5 488 call.short Math.sqrt, v5 489 sta.64 v5 #distance 490 ldobj v3, Body.mass 491 sta.64 v6 492 ldobj v8, Body.mass 493 fmul2.64 v6 494 fdiv2.64 v5 495 sta.64 v6 496 lda.64 v1 497 fsub2.64 v6 498 sta.64 v1 499 inci v7, 1 500 jmp loop2 501loop2_exit: 502 inci v2, 1 503 jmp loop 504loop_exit: 505 lda.64 v1 506 return.64 507} 508